【问题标题】:Window.open in GWT not open correctly with in a call back functionGWT 中的 Window.open 在回调函数中无法正确打开
【发布时间】:2013-07-17 06:02:12
【问题描述】:

我有一个需要下载 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 在回调成功函数中不能正常工作的原因是什么?

【问题讨论】:

    标签: java gwt


    【解决方案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'");
       [...]
    }
    

    【讨论】:

    • 谢谢马诺洛。我所做的与您提供的上述帖子相同。但是该帖子不在从 ajax 上下文调用 window.open 的场景中。顺便说一句,我在那篇帖子中也没有找到你名字的回复?
    • 对不起,这不是我的帖子,我想我以前回答过这个问题,但我没有找到。无论如何,我已经编辑了我的回复以包含所需的代码。
    • 谢谢。我用你的代码。但仍然是同样的问题。我已将框架绑定到我正在使用的网格面板。并调用window.open?我仍然想调用 Window.open 对吗?或者我应该设置调用servlet的url,然后我怎么能像Window.open一样调用它
    • Content-Disposition 中的文件名也只是要下载的文件名吧?不需要和我们在Frame中设置的url一样
    • #1 你不必调用window.open,它只适用于直接链接/按钮。 #2 文件名是您希望用户保存文件的名称(可以与 url 不同)。
    猜你喜欢
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多