简体   繁体   English

Firefox附加pageMod,捕获在contentScriptFile中完成的ajax

[英]Firefox add-on pageMod, catch ajax done in contentScriptFile

my problem is that i need to know when AJAX is done on the page. 我的问题是我需要知道AJAX何时在页面上完成。 I need to know this in my contentScriptFile that i load through pageMod. 我需要在我通过pageMod加载的contentScriptFile中知道这一点。 My add on needs to run every time that the page has been modified: so basically when it loads and every time there is an AJAX call. 我的添加需要在每次修改页面时运行:所以基本上当它加载时以及每次有一个AJAX调用时。

i tried this: 我试过这个:

$(document).ajaxComplete(function() {
     alert("AJAX call completed");
});

but it does not work. 但它不起作用。

is there a way to do this? 有没有办法做到这一点?

edit: my page mod code from main.js: 编辑:我的页面来自main.js的mod代码:

pageMod.PageMod({
     include: "*",
     contentScriptFile: [self.data.url("jquery-1.9.1.min.js"), 
     self.data.url("script.js")],

     onAttach: function(worker){

      var apiKey = require("sdk/simple-prefs").prefs.apiKey;
      var ignoreList = require("sdk/simple-prefs").prefs.ignoreList;

      worker.port.emit("prefSet", [ignoreList, apiKey]);

      }

});

Put this not in a content script: Im not sure how you will identify the content window of the script. 不要把它放在内容脚本中:我不确定如何识别脚本的内容窗口。 I dont know sdk so well. 我不太了解sdk。 But see the area CONTENT_WINDOW_OF_CONTENT_SCRIPT 但请参阅CONTENT_WINDOW_OF_CONTENT_SCRIPT区域

const { Ci, Cu, Cc, Cr } = require('chrome'); //const {interfaces: Ci, utils: Cu, classes: Cc, results: Cr } = Components;
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/devtools/Console.jsm');

var observers = {
    'http-on-modify-request': {
        observe: function (aSubject, aTopic, aData) {
            console.info('http-on-modify-request: aSubject = ' + aSubject + ' | aTopic = ' + aTopic + ' | aData = ' + aData);
            var httpChannel = aSubject.QueryInterface(Ci.nsIHttpChannel);
            var requestUrl = httpChannel.URI.spec
            var goodies = loadContextAndGoodies(aSubject, true);
            if (goodies.contentWindow) {
               if (goodies.contentWindow == CONTENT_WINDOW_OF_CONTENT_SCRIPT) {
                    //do something here
               }
            }
        },
        reg: function () {
            Services.obs.addObserver(observers['http-on-modify-request'], 'http-on-modify-request', false);
        },
        unreg: function () {
            Services.obs.removeObserver(observers['http-on-modify-request'], 'http-on-modify-request');
        }
    }
};

Then in that same scope add in this helper function: 然后在同一范围内添加此辅助函数:

function loadContextAndGoodies(request, return_goodies) {
  var loadContext = null;

  if (request instanceof Ci.nsIRequest) {
      try {
          if (request.loadGroup && request.loadGroup.notificationCallbacks) {
              loadContext = request.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
          }
      } catch (ex) {
        console.exception('request loadGroup with notificationCallbacks but oculd not get nsIloadContext', ex);
      }
      if (!loadContext) {
        try {
            if (request.notificationCallbacks) {
                loadContext = request.notificationCallbacks.getInterface(Ci.nsILoadContext);
            }
        } catch (ex) {
          console.exception('request has notificationCallbacks but could not get nsILoadContext', ex);
          /* start - noit's backup try, it might be redundant (im not sure) as Wladamir Palant didn't have this way*/
          try {
            var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
            loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
          } catch (ex) {
            console.exception('backup method failed:' ex);
          }
          /* end - my backup try, it might be redundant as Wladamir Palant didn't have this way*/
        }
      }
  } else {
    console.warn('request argument is not instance of nsIRequest')
  }

  if (return_goodies) {
    if (!loadContext) {
      return null;
    }

    var contentWindow = loadContext.associatedWindow;
    var DOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
                                     .getInterface(Ci.nsIWebNavigation)
                                     .QueryInterface(Ci.nsIDocShellTreeItem)
                                     .rootTreeItem
                                     .QueryInterface(Ci.nsIInterfaceRequestor)
                                     .getInterface(Ci.nsIDOMWindow);
    var gBrowser = DOMWindow.gBrowser;
    if (gBrowser) {
      var tab = gBrowser._getTabForContentWindow(contentWindow.top);
      var browser = tab.linkedBrowser;
    } else {
      var tab, browser = null;
    }
    var goodies = {
      loadContext: loadContext,
      DOMWindow: DOMWindow,
      gBrowser: gBrowser,
      contentWindow: contentWindow,
      browser: browser,
      tab: tab
    };

    return goodies;
  } else {
    return loadContext;
  }
}

To start observing 开始观察

To start start obseving all requests do this (for example on startup of your addon) 要开始观察所有请求,请执行此操作(例如,在启动插件时)

for (var o in observers) {
    observers[o].reg();
}

To stop observing 停止观察

Its important to stop observring (make sure to run this at least on shutdown of addon, you dont want to leave the observer registered for memory reasons) 停止观察是很重要的(确保至少在关闭插件时运行它,你不想因为内存原因而让观察者注册)

for (var o in observers) {
    observers[o].unreg();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM