在chrome扩展程序中,我有一个后台脚本,该脚本将使用XMLHttpRequest
获取一些所需的数据。
// note that this code is in the global scope i.e. outside of any function
// also note that I got this code from the page talking about XMLHttpRequest
var myData = [];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = handleStateChange;
xhr.open("GET", "...", true);
xhr.send();
function handleStateChange() {
myData = Object.values(JSON.parse(xhr.responseText));
}
我想知道何时xor.send()
将运行。
我发现每次我按下按钮重新加载扩展名时,都会调用xhr.send()
。我还观察到打开一个新的选项卡/窗口不会导致后台脚本再次运行。
我还发现了这个page,背景页面被“加载”和“卸载”,但是它几乎没有说明何时代码在背景的全局范围内< em> script 运行。
它仅在安装/重新加载扩展程序时运行吗?
答案 0 :(得分:2)
由于扩展名的背景页面的一个副本在用户的所有选项卡和窗口(响应所有按选项卡的资源)的全局位置上全局存在,因此您将永远不会看到启动过程(浏览器重新启动和更新期间除外)。永远不会被暂停。您可以启动任务管理器,查看扩展程序的背景是否始终存在,并保持相同的Process ID
,表明它没有被关闭。还有一个可选的Keepalive count
列,它显示有多少活动使一个进程保持活动状态,带有-
的任务可能被强制持久化,但是似乎–
发生是出于多种原因。
如果后台页面具有persistent:false
并且满足所有其他条件将其关闭,则可以将其关闭,直到发生下一个事件(侦听器,getBackgroundPage()
等)。然后,下一个需要它的事件将加载执行全局范围的后台页面,等等,作为设置预期要调用的侦听器的一部分。
您可以转到chrome://extensions
启用开发人员模式,然后检查扩展程序的后台页面以查看persistent
和permissions: [chrome.webRequest]
的干扰:
如果在没有显式设置的情况下仍然发生persistent:true
行为,则可能是背景页面的全局范围内的状态引起的。最好还是遵循migration guide,例如,如果您要从首次启动起就将数据持久化到挂起之外,则您的xhr请求属于启动公司:
chrome.runtime.onStartup.addListener(function() {
var xhr = new XMLHttpRequest()
xhr.onreadystatechange = handleStateChange
xhr.open("GET", "...", true)
xhr.send()
function handleStateChange() {
chrome.storage.local.set({ myData:
JSON.stringify(Object.values(JSON.parse(xhr.responseText)))});
}
})
这应该大致具有与persistent:true
在全局范围内运行此代码的等效行为,但是xhr可以被垃圾回收,因为这不是其他侦听器的范围,等等。(因为chrome标记了资源类型,例如网络套接字是导致无法挂起的原因,请务必将其移出范围。)调整后,即使浏览器仍未自动挂起,您也可以通过在后台页面检查中重新加载扩展来测试行为。 >
如果您不想适应persistent:false
,那么我将在清单中设置persistent:true
而不是依赖当前的隐式行为。 (即使您无法导致测试系统挂起,如果设置了persistent:false
,具有更大内存压力或其他情况的系统也可能会卸载后台页面。)
如果您发现Process ID
在变化,但是您没有遇到任何问题,那么您会很幸运。该系统确保您的全局作用域在为您的传入请求重新启动后台页面时运行,但是it does not make sure any asynchronous parts have completed。例如,如果需要启动后台页面以查看您是否具有适当的侦听器,则必须启动ajax,但是当全局范围的同步部分运行完毕时(可能在响应之前),可以调用该侦听器。 。因此,如果挂起工作正常,您将无法指望MyData
。
如果要将xhr请求保留在全局范围内并正确支持persistent:false
,则需要确保侦听器立即注册,但在内部等待myData
。例如,如果myData
是handleStateChange()
所解决的承诺,则其他侦听器可以使用myData.then(..)
发出异步响应,并从后台页面的最新重启中获得ajax响应,而不是存储在chrome local中。自〜安装以来存储。