addEventListener(“load”,...)导致过多的XmlHttpRequests?

时间:2014-11-06 19:22:55

标签: javascript apache firefox xmlhttprequest firefox-addon

假设我在Firefox插件中运行了以下JavaScript代码,该插件应在页面加载时执行XmlHttpRequest

function my_fun(){

var xmlHttpConnection = new XMLHttpRequest();
    xmlHttpConnection.open('GET', globalUrl+'/call_this.php', true);
    xmlHttpConnection.onreadystatechange=function(){
        if (xmlHttpConnection.readyState == 4 && xmlHttpConnection.status == 200) {
            var serverResponse = xmlHttpConnection.responseText;
            do_stuff();
            clearTimeout(xmlHttpTimeout);
            xmlHttpConnection.abort();
       }
 };

 xmlHttpConnection.send(null);
 xmlHttpTimeout = setTimeout(function (){
                                 do_other_stuff();
                                 xmlHttpConnection.abort();
                                 clearTimeout(xmlHttpTimeout);
                             },5000);
}

container.addEventListener("load", my_fun, true);

调用my_fun()时,我的Apache服务器的访问日志如下所示:

<client-ip> - - [06/Nov/2014:10:40:04 -0500] "GET /call_this.php HTTP/1.1" 200 1 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0"

进一步假设我的服务器上有4个客户端连接。在1秒的范围内,此行可以在访问日志中同时显示数十个(有时超过50)次,而ping有时只来自1个客户端。大多数情况下,每秒ping次数低于5次,但call_this.php偶尔会出现峰值。

为什么会这样?我怀疑container.addEventListener("load", my_fun, true);出了问题。这是否超过了加载次数,例如,如果页面包含多个加载的隐藏URL?如果是这样,我该如何解决这个问题呢? (编辑:观察员服务会更好吗?)

2 个答案:

答案 0 :(得分:2)

是。我看起来不对劲:

检查此行:

container.addEventListener("load", function(){my_fun();}, true);

或更改功能声明:

function my_fun(){
...

my_fun = function(){
...

答案 1 :(得分:1)

找到答案。我确实认为事件监听器存在问题。但由于上面的代码是在Firefox插件中,一个好方法是使用Mozilla观察者。以下观察者显着减少了服务器的ping数(经验测试)。

特别感谢Noitidart,他为不同的问题提供了类似的解决方案。

var myObserver = {
register: function() {
    var observerService = Components.classes["@mozilla.org/observer-service;1"]
    .getService(Components.interfaces.nsIObserverService);
    observerService.addObserver(this, TOPIC_MODIFY_REQUEST, false);
},
    //observe function to capture the changed event
    observe : function(aSubject, aTopic, aData) {
        if (TOPIC_MODIFY_REQUEST == aTopic ) {
            var url;
            aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);

            url = aSubject.URI.spec;
            url = encodeURIComponent(url);

            var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
            if (oHttp.loadFlags & Components.interfaces.nsIHttpChannel.LOAD_INITIAL_DOCUMENT_URI) {
                //is top level load
                my_fun(); //Same function as in original question
            }
        }
    }       
} 

myObserver.register();
相关问题