Javascript 在阻止webRequest处理程序中使用异步调用 总结

Javascript 在阻止webRequest处理程序中使用异步调用 总结,javascript,firefox,firefox-addon,firefox-addon-webextensions,Javascript,Firefox,Firefox Addon,Firefox Addon Webextensions,我使用的是浏览器.webRequest.onBeforeRequest处理程序。我需要阻止webRequest,直到从处理程序中对异步方法的调用中获得信息。我该怎么做 细节 首先,我为这个冗长的问题道歉。但我希望有人能帮忙 我有一个嵌入式扩展,其中包含一个browser.webRequest.onBeforeRequest(我现在需要使用嵌入式扩展来处理一些SDK遗留代码) browser.webRequest.onBeforeRequest回调函数连接到SDK扩展并指示其执行某些功能。当从任务

我使用的是
浏览器.webRequest.onBeforeRequest
处理程序。我需要阻止webRequest,直到从处理程序中对异步方法的调用中获得信息。我该怎么做

细节 首先,我为这个冗长的问题道歉。但我希望有人能帮忙

我有一个嵌入式扩展,其中包含一个
browser.webRequest.onBeforeRequest
(我现在需要使用嵌入式扩展来处理一些SDK遗留代码)

browser.webRequest.onBeforeRequest
回调函数连接到SDK扩展并指示其执行某些功能。当从任务中完成回复时,SDK会向webextension发送回复。我在
browser.runtime.sendMessage
中使用了
wait
,以确保在收到SDK的回复之前停止执行。要使用
wait
,我必须使用
async
(但实际上我不想要
async
函数)。当我不使用
wait
时,我只在循环完成其所有迭代后从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"
  ]
}
{
  "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"
}
}
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
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"]}
);
3)
manifest.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"
  ]
}
{
  "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"
}
}
各国(强调我国):

要取消或重定向请求,请首先将
extraInfoSpec
数组参数中的
包含到
addListener()
。然后,在侦听器函数中,返回一个对象,设置适当的属性:

  • 要取消请求,请包含一个值为true的属性
    cancel
  • 要重定向请求,请包含一个属性
    redirectUrl
    ,该属性的值设置为要重定向到的URL
从Firefox 52开始,监听器不必返回
BlockingResponse
,而可以返回一个由
BlockingResponse
解析的。这使侦听器能够异步处理请求。

你似乎没有做上述任何一件事。因此,事件是完全异步处理的,在处理程序返回之前不可能延迟请求。换句话说,正如当前编写的那样,您的
webRequest.onBeforeRequest
对webRequest绝对没有影响。您的处理程序刚刚收到webRequest正在处理的通知

要完成所需操作,请将请求延迟到执行某些异步操作之后,您需要:

  • “webRequestBlocking”
    添加到manifest.json权限中:

    “权限”:[
    “活动标签”,
    “网络请求”,
    “webRequestBlocking”,
    ""
    ],
    
  • extraInfoSpec
    数组参数中的
    “阻塞”
    传递到
    addListener()

    browser.webRequest.onBeforeRequest.addListener(
    阿莫德,
    {URL:[“”],
    类型:[“主框架”]},
    [“封锁”]
    );
    
  • 从处理程序返回一个承诺,该承诺通过
    BlockingResponse
    解析:

    函数aMethod(){
    //具体如何编码将取决于您正在做什么。
    var承诺=[];
    log(“在webExt:inside-aMethod中”);
    对于(变量x=0;x<2;x++){
    log(“循环迭代:+x”);
    如果(标志==真){
    控制台日志(“内部if”);
    log(“将向SDK发送消息”);
    promises.push(browser.runtime.sendMessage(“发送到sdk”)。然后(reply=>{
    若有(答复){
    log(“在webExt:+reply.content中”);
    }否则{
    控制台日志(“”);
    }
    });
    }否则{
    控制台日志(“其他内部”);
    }
    }
    返回Promise.all(promises).then(function(){
    //使用空对象解析,该对象是允许
    //解决后,webRequest将正常完成。
    返回{};
    });
    }