我正在使用browser.webRequest.onBeforeRequest
处理程序。我需要阻止webRequest,直到我从处理程序内的异步方法调用回来。我怎么能这样做?
首先,我为长期问题道歉。但我希望有人能提供帮助。
我有一个嵌入式扩展,其中包含browser.webRequest.onBeforeRequest
(我现在需要使用嵌入式扩展来处理一些SDK遗留代码)。
browser.webRequest.onBeforeRequest
回调函数连接到SDK扩展并指示它执行某些功能。当SDK从任务完成时,SDK会向webextension发送回复。我在await
中使用了browser.runtime.sendMessage
来确保在我收到SDK的回复之前停止执行。要使用await
,我必须使用async
(但实际上我不想要async
函数)。当我不使用await
时,我只在循环完成所有迭代后才得到SDK的回复,而不是每次迭代。
下面的示例代码包含许多用于调试的控制台消息,仅用于监视执行情况。
问题是:我没有得到可靠的结果。在某些情况下(并非所有情况),http请求在SDK代码生效之前就会消失。我可以识别这一点,因为请求属性必须受SDK代码的影响。控制台按预期显示执行顺序。但是,http请求不受SDK的影响(在某些情况下)。
在这个简单的例子中,SDK只是向webextension发送消息,但假设它执行某些功能,读/写操作等。所有SDK任务必须在请求结束之前完成。
我真正需要的是保证在执行所有SDK代码之前Web请求不会消失。
参考MDN文档,它说browser.webRequest.onBeforeRequest是一个async
函数。我想知道这是否是问题的根源?如果是这样,如何强制它同步?
embedding-extension [directory]
- index.js
- package.json
- webextension [directory]
- main.js
- manifest.json
1)package.json
:
{
"title": "testhybrid",
"name": "testhybrid",
"version": "0.0.1",
"description": "A basic add-on",
"main": "index.js",
"author": "",
"engines": {
"firefox": ">=38.0a1",
"fennec": ">=38.0a1"
},
"license": "MIT",
"hasEmbeddedWebExtension": true,
"keywords": [
"jetpack"
]
}
2)index.js
:
const webExtension = require("sdk/webextension");
console.log("in SDK: inside embedding extension");
// Start the embedded webextension
webExtension.startup().then(api => {
const {browser} = api;
browser.runtime.onMessage.addListener((msg, sender, sendReply) => {
if (msg == "send-to-sdk") {
console.log("in SDK: message from webExt has been received");
sendReply({
content: "reply from SDK"
}); //end send reply
}//end if
}); //end browser.runtime.onMessage
}); //end webExtension.startup
3)manifest.json
:
{
"manifest_version": 2,
"name": "webExt",
"version": "1.0",
"description": "No description.",
"background": {
"scripts": ["main.js"]
},
"permissions": [
"activeTab",
"webRequest",
"<all_urls>"
],
"browser_action": {
"default_icon": {
"64": "icons/black-64.png"
},
"default_title": "webExt"
}
}
4)main.js
:
var flag=true;
async function aMethod() {
console.log("in webExt: inside aMethod");
for(var x=0; x<2; x++)
{
console.log("loop iteration: "+x);
if(flag==true)
{
console.log("inside if");
console.log("will send message to SDK");
const reply = await browser.runtime.sendMessage("send-to-sdk").then(reply => {
if(reply)
{
console.log("in webExt: " + reply.content);
}
else {
console.log("<<no response message>>");
}
});
}//end if flag
else
{
console.log("inside else");
}//end else
}//end for
}
browser.webRequest.onBeforeRequest.addListener(
aMethod,
{urls: ["<all_urls>"],
types: ["main_frame"]}
);
答案 0 :(得分:2)
webRequest.onBeforeRequest
documenation州(强调我的):
要取消或重定向请求,请先将
"blocking"
数组参数中的extraInfoSpec
包括在addListener()
中。然后,在侦听器函数中,返回BlockingResponse
对象,设置适当的属性:
- 取消请求,请包含值为true的属性
cancel
。- 要重定向请求,请添加一个属性
redirectUrl
,其值设置为您要重定向的网址。从Firefox 52开始,侦听器可以返回Promise而不是返回
BlockingResponse
,而{{3}}将使用BlockingResponse
进行解析。这使侦听器能够异步处理请求。
您似乎没有完成上述任何操作。因此,事件是完全异步处理的,在处理程序返回之前不可能延迟请求。换句话说,正如目前所写,webRequest.onBeforeRequest
对webRequest完全没有影响。您只需通知处理程序webRequest正在处理中。
要完成您的需求,请将请求延迟到执行某些异步操作之后,您需要:
将"webRequestBlocking"
添加到您的 manifest.json 权限中:
"permissions": [
"activeTab",
"webRequest",
"webRequestBlocking",
"<all_urls>"
],
将"blocking"
数组参数中的extraInfoSpec
传递给addListener()
:
browser.webRequest.onBeforeRequest.addListener(
aMethod,
{urls: ["<all_urls>"],
types: ["main_frame"]},
["blocking"]
);
从您的处理程序返回一个Promise,它以BlockingResponse
:
function aMethod() {
//Exactly how this is coded will depend on exactly what you are doing.
var promises = [];
console.log("in webExt: inside aMethod");
for (var x = 0; x < 2; x++) {
console.log("loop iteration: " + x);
if (flag == true) {
console.log("inside if");
console.log("will send message to SDK");
promises.push(browser.runtime.sendMessage("send-to-sdk").then(reply => {
if (reply) {
console.log("in webExt: " + reply.content);
} else {
console.log("<<no response message>>");
}
});
} else {
console.log("inside else");
}
}
return Promise.all(promises).then(function(){
//Resolve with an empty Object, which is a valid blockingResponse that permits
// the webRequest to complete normally, after it is resolved.
return {};
});
}