在加载之前从内容脚本向加载项发出消息

Emit message to add-on from content script onbeforeunload?

本文关键字:加载项 消息 脚本 加载      更新时间:2023-09-26

我有一个内容脚本,用来计算用户查看页面的时间。为此,我在每个页面中注入一个内容脚本,启动一个计时器,然后在触发onbeforeunload事件时向插件发回一条消息。

然而,该消息似乎从未传递到后台脚本。

假设我的main.js是这样的:

var pageMod = require('page-mod'),
    self = require("self");
pageMod.PageMod({
  include: "http://*",
  contentScriptFile: [self.data.url('jquery.min.js'),
                      self.data.url('content.js')],
  onAttach: function(worker) {
    worker.port.on('pageView', function(request) {
      console.log("Request received");
    });
  }
});

我可以使用以下代码向main.js发送消息,没有问题。

self.port.emit('pageView', { visitTime: time });

然而,当用户离开页面时,我尝试这样做时遇到了一个问题。当我这样做时,永远不会收到消息:

$(window).bind('onbeforeunload', function(e) {
  self.port.emit('pageView', { visitTime: time });
  // This should prevent the user from seeing a dialog.
  return undefined;
});

我也试过听beforeunload,但也不管用。可能是什么问题?

内容脚本在Firefox浏览器插件中访问的window对象是一个代理对象,可能有点喜怒无常。使用window.addEventListener即可。

window.addEventListener('beforeunload', function(e) {
  # Do stuff then return undefined so no dialog pops up.
  return undefined
});

onbeforeUnload事件不是同步的,因此浏览器在页面完成之前会垃圾收集页面。使用同步AJAX请求:

function Data() 
 {
 var client = new XMLHttpRequest();
 client.open("GET", "/request", false); // third paramater indicates sync xhr
 client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
 client.send({ visitTime: time });
 client.onreadystatechange = emitter;
 }
function emitter()
 {
 self.port.emit('pageView', { visitTime: time });
 }

或者作为替代返回字符串。