GWT中的Window.open无法在回调函数中正确打开

时间:2013-07-17 06:02:13

标签: java gwt

我遇到需要下载excel文件的情况。所以我用它来Window.open。问题是我需要在调用Window.open之前检查文件是否在服务器位置是exsist。因此,当用户点击下面按钮时,会发生以下呼叫,

public void onClick(Button button, EventObject e) {
   final String url = GWT.getModuleBaseURL() + "fileupload/dailyLogReport?param1=param1                                 
   openFileDownloadWindow(url,fileName);
}

public void openFileDownloadWindow(final String url,String fileName){
     CommonServiceAsync serviceAsyn = CommonService.Util.getInstance();
     final AsyncCallback callback = new AsyncCallback() {
         public void onSuccess(Object result) 
         {                              
             isFileExsist = (Boolean)result;

             if(isFileExsist){
            Window.open( url, "_blank", "status=0,toolbar=0,menubar=0,location=0");
             }else{
                Window.alert("File not found."); 
             }

         }              
         public void onFailure(Throwable caught) 
         { 
                MessageBox.alert("Error", "Error while getting data"
                        + caught.getMessage());
         } 
      };  
      // calling of the action
      serviceAsyn.isDailyLogFileExsists(fileName, callback);    

}

但问题是如果我把Window.open放在成功之内它只需打开一个Window并快速关闭它而不下载文件。但是,如果我将Window.open直接放在onClick方法中,它会成功打开窗口弹出并成功下载文件。但由于我必须通过检查文件是否存在来有条件地下载文件,我不能将Window.open放在onClick上。

Window.open在回调成功函数内部无法正常工作的原因是什么?

1 个答案:

答案 0 :(得分:1)

问题是弹出窗口阻止程序。

当您单击元素时,您可以打开一个新窗口,因为浏览器认为这是一个故意的用户操作来打开窗口。

否则,浏览器会阻止异步块中的任何window.open,因为它认为它可能是恶意代码用完了用户控件。

最好的解决方案是在iframe中打开文件,但是您必须在服务器端设置适当的内容处置标头,这会导致浏览器显示“保存”对话框。

客户代码:

  // Create a new iframe
  final Frame f = new Frame();
  f.setUrl(url_to_my_excel_file");
  // Set a size of 0px unless you want the file be displayed in it
  // For .html images .pdf, etc. you must configure your servlet
  // to send the Content-Disposition header
  f.setSize("0px", "0px");
  RootPanel.get().add(f);
  // Configure a timer to remove the element from the DOM
  new Timer() {
    public void run() {
      f.removeFromParent();
    }
  }.schedule(10000);

服务器代码:

protected void doGet( HttpServletRequest req, HttpServletResponse resp ) throws ServletException, IOException {
   [...]
   // Set the appropriate type for your file 
   resp.setContentType("application/vnd.ms-excel");
   // Mandatory if you want the browser open the save dialog
   resp.setHeader("Content-Disposition:", "attachment;filename='my_excel_file.xls'");
   [...]
}