1

我有一种情况,我需要下载一个 excel 文件。所以我为此使用了 Window.open。问题是我需要在调用 Window.open 之前检查文件是否存在于服务器位置。因此,当用户单击以下调用的下载按钮时,

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.open 直接放在 onClick 方法中,它会成功打开弹​​出窗口并成功下载文件。但是由于我必须通过检查文件是否存在来有条件地下载文件,所以我不能将 Window.open 放在 onClick 中。

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

4

1 回答 1

1

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

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

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

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

客户代码:

  // 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'");
   [...]
}
于 2013-07-17T06:13:37.737 回答