【问题标题】:GWT Script Injection Failure with PubNubPubNub 的 GWT 脚本注入失败
【发布时间】:2012-10-10 19:37:54
【问题描述】:

GWT 新手,但到目前为止我很喜欢。我确实有一个很容易重现的问题。这对我来说是个大问题,因为我想为 PubNub 创建一个 GWT 模块 - 我们内部使用的实用程序。

我创建了一个演示项目来测试封装,我发现 ScriptInjector/Pubnub 存在一个有趣的问题。

起初我按照 PubNub 的说明进行操作。注意:我已经包含了我的测试帐户的密钥。随意使用它们。

按照说明,我将这两项放在 GWT 项目的 html 文件中(指定了我的密钥):

<div pub-key="pub-b8b75fbd-c4cf-4583-bab9-424af7a7f755" sub-key="sub-5e843c94-1193-11e2-bba9-b116c93082cf" ssl="off" origin="pubsub.pubnub.com" id="pubnub"></div>
<script src="http://cdn.pubnub.com/pubnub-3.1.min.js"></script>

当我这样做时,我可以使用 JSNI 访问 pubnub。这一切都很好。

如果我在此处删除标记并使用以下代码注入脚本,则不起作用。我知道脚本会注入,因为我可以看到成功消息,并且可以在 Chrome 的开发者工具中看到脚本。

          ScriptInjector.fromUrl("http://cdn.pubnub.com/pubnub-3.1.js").setCallback(
                  new Callback<Void, Exception>() {
                     public void onFailure(Exception reason) {
                       Window.alert("Script load failed.");
                     }
                     public void onSuccess(Void result) {
                       Window.alert("Script load success.");
                     }
                  }).inject();

我觉得这一定与使用延迟脚本访问 DOM 有某种关系,或者因为脚本不是 DOM 的一部分。它正在尝试访问设置 div,但无法...(只是我的猜测)

有什么想法吗?我需要将项目移出 html 文件,因为我需要将此项目模块化以用于其他更大的项目。任何帮助将不胜感激。

(PS,我也尝试创建 html 小部件,并将它们添加到 EntryPoint。这也会根据我在 Chrome 中的开发人员工具中的浏览将标签添加到页面,但它无法工作,就像 ScriptInjector 失败一样。 )

编辑:这是一个尽可能简单的项目来演示问题:

html 文件:

结束正文标签上方:

<div pub-key="pub-b8b75fbd-c4cf-4583-bab9-424af7a7f755" sub-key="sub-5e843c94-1193-11e2-bba9-b116c93082cf" ssl="off" origin="pubsub.pubnub.com" id="pubnub"></div>
<script src="http://cdn.pubnub.com/pubnub-3.1.min.js"></script>
<script src="pubnubWrapper.js"></script>

pubnubWrapper.js(基本上是 pubnub 网站上的内容):

function subToPubNub(){
    PUBNUB.subscribe({
        channel    : "hello_world",      // CONNECT TO THIS CHANNEL.
 
        restore    : false,              // STAY CONNECTED, EVEN WHEN BROWSER IS CLOSED
                                         // OR WHEN PAGE CHANGES.
 
        callback   : function(message) { // RECEIVED A MESSAGE.
            alert(message);
        },
 
        disconnect : function() {        // LOST CONNECTION.
            alert(
                "Connection Lost." +
                "Will auto-reconnect when Online."
            )
        },
 
        reconnect  : function() {        // CONNECTION RESTORED.
            alert("And we're Back!")
        },
 
        connect    : function() {        // CONNECTION ESTABLISHED.
 
            PUBNUB.publish({             // SEND A MESSAGE.
                channel : "hello_world",
                message : "Hi from PubNub."
            })
 
        }
    })
}

ScriptTest.java:

public class ScriptTest implements EntryPoint {
    public void onModuleLoad() {
        //add a button to sub to pubnub
        Button subButton = new Button("Sub");
        //add the event handler for button
        subButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                //sub to pubnub
              callSub();
            }
          });
        RootPanel.get().add(subButton);
    }
    public native void callSub() /*-{
        //call my wrapper to pubnub
        $wnd.subToPubNub();
    }-*/;
}

这一切都照原样运行。

如果您从 html 文件中删除 pubnub 脚本并使用脚本注入器添加它,则会失败。如果将脚本添加到 gwt.xml 文件中,则会失败。

有什么想法吗?

【问题讨论】:

    标签: gwt pubnub


    【解决方案1】:

    您可以发布您的 JSNI 代码吗?
    我敢打赌,您是通过 $wnd 变量访问 PubNub 对吧?
    如果您将脚本标签放在模块的 xml 文件中,则 pubnub 代码将加载到主机的页面窗口中(您可以使用 Chrome DeveloperTools 进行检查)。

    ScriptInjector 默认情况下不会将其加载到那里,而是在 GWT 命名空间中。 因此,为了将其加载到主机的窗口命名空间中,您必须将 TOP_WINDOW 传递给 ScriptInjector

    ScriptInjector.fromUrl("http://cdn.pubnub.com/pubnub-3.1.js").setCallback(
        new Callback<Void, Exception>() {
            public void onFailure(Exception reason) {
                Window.alert("Script load failed.");
            }
            public void onSuccess(Void result) {
                Window.alert("Script load success.");
            }
    }).setWindow(ScriptInjector.TOP_WINDOW).inject();
    

    【讨论】:

    • 好主意,但您似乎无法将 fromUrl 注入到 TOP_WINDOW 中。我会尽量把我的代码写成超小的代码,然后在这里发布。
    • 什么意思?根据Javadoc可以注入到TOP_WINDOW。
    • 对不起,我打错了。您的代码是正确的,并将其放入文档的 中。注射仍然不起作用。我将建立一个简单的项目来显示问题。
    • 使用 Chrome 开发者工具检查 PubNub 是否在 $wnd 中正确设置
    • Umit,我会检查 $wnd。请参阅上面的编辑。我发布了一个简单的示例供大家查看。
    猜你喜欢
    • 2011-08-09
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    相关资源
    最近更新 更多