【问题标题】:GWT: Open window after RPC is prevented by popup blockerGWT:弹出窗口阻止程序阻止 RPC 后打开窗口
【发布时间】:2012-11-07 20:35:35
【问题描述】:

您好,我有以下代码:

    button.addClickHandler( new ClickHandler( ) {
        @Override   
        public void onClick( ClickEvent event ) {    
             Call 1 --> Window.open( publicBookingUrl, "_blank", null );                
            dispatcher.execute( new HasServicesAction(true), 
                    new ActionCallback<SomeResult>( ){       
                @Override 
                public void onSuccess( SomeResult result ) {
             Call 2 --> Window.open( publicBookingUrl, "_blank", null );
                } 
            });  
        }        
    });

In Call 1 弹出窗口阻止程序不会阻止弹出窗口打开。它成功地在新选项卡或新窗口中打开一个窗口。然而,在 Call2 中,弹出窗口阻止程序会阻止弹出窗口,因此用户必须明确启用弹出窗口。 我找到了一篇解释其背后原因的帖子:https://groups.google.com/forum/?fromgroups=#!topic/google-web-toolkit/V0s7goJxuhc 不幸的是,这个解决方案对我不起作用。

有人知道为什么会这样吗?我们怎样才能解决这个问题?

提前致谢。

【问题讨论】:

    标签: javascript gwt window


    【解决方案1】:

    正如您链接到的页面所指出的那样,只有在用户直接操作的情况下才能打开窗口。您可以通过在 RPC 调用之前打开窗口并在 RPC 调用返回后设置窗口的 URL 来解决此问题。 GWT 的内置 Window 不会暴露所有底层 window 对象的属性,因此需要自定义实现:

    public class MyWindow extends JavaScriptObject {
      // All types that extend JavaScriptObject must have a protected,
      // no-args constructor. 
      protected MyWindow() {}
    
      public static native MyWindow open(String url, String target, String options) /*-{
        return $wnd.open(url, target, options);
      }-*/;
    
      public native void close() /*-{
        this.close();
      }-*/;
    
      public native void setUrl(String url) /*-{
        if (this.location) {
          this.location = url;
        }
      }-*/;
    }
    

    然后在您的点击处理程序中:

    public void onClick(ClickEvent event) {
      final MyWindow window = MyWindow.open(null, "_blank", null);
    
      dispatcher.execute(new HasServicesAction(true), 
          new ActionCallback<SomeResult>( ){       
            @Override 
            public void onSuccess(SomeResult result) {
              if (result.isGood()) {
                window.setUrl(publicBookingUrl);
              } else {
                window.close();
              }
            }
          });  
    }
    

    请注意,如果您对setUrl() 的调用更改了打开窗口的origin,您将无法修改任何属性或调用任何函数。

    【讨论】:

    • 问题是我可能不需要弹出窗口,所以这个解决方案对我不起作用。条件由 RPC 返回的结果决定。
    • 您可以在MyWindow 类中添加一个close() 方法来处理这个问题——我会更新我的答案。
    • 完美!如果没有,则需要将 final 添加到 MyWindow 类中我收到一些关于 JavaScriptObject 子类的错误必须是 final。
    【解决方案2】:

    摆脱弹出窗口。请改用 PopupDialog。

    如果用户禁用了弹出窗口并且您找到了一种显示方式,那么该用户会怎么看您?

    【讨论】:

    • window.open 有合法用途。
    • 可能是。但是,如果用户阻止了弹出窗口,那么破解它是不“合法的”。如果您因任何原因无法使用 PopupDialog,请告诉他们为您的网站启用弹出窗口。
    • 一个例子:尝试在弹出对话框中显示 PDF(或者实际上,提供下载)。对于您的解决方法,我如何知道弹出窗口阻止程序是否处于活动状态(告诉用户禁用它)?
    • @PaŭloEbermann 我确实通过打开一个新标签在我的一个应用程序中提供 PDF 下载。不同之处在于,当用户启动操作(即用户单击下载按钮或图标)时,浏览器允许这样做。当您尝试在没有用户操作的情况下以编程方式打开新选项卡时,浏览器会阻止它。
    • 是的......我们只是改变了我们应用程序的行为,所以按钮单击首先执行 GWT-RPC 调用,然后在返回时加载 PDF(这样我们可以向用户提供一些反馈,以防万一有些东西不起作用)。并非完全没有用户操作,但我想浏览器看不出区别。目前解决方法是告诉用户(通过邮件)允许它,但我想从我的应用程序中检查它。或者我会尝试 Jason 的解决方案。
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-31
    • 1970-01-01
    相关资源
    最近更新 更多