有没有办法在不锁定整个浏览器的情况下使用chrome.webRequest暂停HTTP请求?

时间:2012-01-24 16:30:00

标签: javascript google-chrome-extension

我想将用chrome.webRequest.onBeforeSendHeaders拦截的标题显示给用户进行编辑,最好使用chrome.tabs.executeScript。但是,chrome.tabs.executeScript是异步的,我找不到等待它返回而不冻结整个浏览器的方法。

换句话说,我的目标是下面给出的代码,除了使用HTML UI并且不冻结任何不相关的标签。

chrome.webRequest.onBeforeSendHeaders.addListener(
    function(details) {
    for (var i = 0; i < details.requestHeaders.length; ++i) {
      if (details.requestHeaders[i].name === 'User-Agent') {
          var foo = prompt('User-Agent', details.requestHeaders[i].value);
          // chrome.tabs.executeScript(details.tabId,{code:""});
          //^create a nice HTML overlay & pass the user input back
          details.requestHeaders[i].value = foo;
         break;
      }
    }
    return {requestHeaders: details.requestHeaders};
  },
  {urls: ["http://*/*"], types: ["main_frame"]},
  ["blocking", "requestHeaders"]);

如果也不可能知道,因为我可以提交功能请求。

2 个答案:

答案 0 :(得分:0)

您应该使用promise,例如,您可以创建一个睡眠命令,该命令保留当前线程,直到X秒后(或完成头文件的编辑后)返回promise值为止。

const sleep = async seconds => {
    return new Promise(async(resolve)=>{
        setTimeout(resolve, seconds * 1000);
    });
}

请注意,必须在异步线程上调用异步函数,因此您应该在异步函数内部启动应用程序(或仅侦听器函数)。如果您愿意的话,这可以是一个匿名函数(又名没有名字的函数):

(async()=>{
    await sleep(2);
    // do something after waiting 2 seconds.
})();

在您的情况下,一个可行的示例是将阻塞的侦听器函数声明为异步的,如下所示:

const promptUserToEditHeaders = async details => {
    return new Promise(async(resolve)=>{
        // prompt the user to edit the request headers
        // then call resolve() when you are done editing headers
    });
}

chrome.webRequest.onBeforeSendHeaders.addListener(
    async details => {
        await promptUserToEditHeaders(details);
    },
    {urls: ["http://*/*"], types: ["main_frame"]},
    ["blocking", "requestHeaders"]
);

详细了解JavaScript承诺:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference

了解有关异步和等待的更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Promise和async / await都是进行异步调用的非常有用的方法。

答案 1 :(得分:-1)

我不确定这是否有用,但值得一试。

您可以设置一个while循环来保存返回,直到您执行的脚本通过Message Passing返回消息。此外,您需要在清单中使用webRequestBlocking权限(您可能已经拥有)。

chrome.webRequest.onBeforeSendHeaders.addListener(
    function(details) {
        var holdReturn = false;

        for (var i = 0; i < details.requestHeaders.length; ++i) {
            if (details.requestHeaders[i].name === 'User-Agent') {
                holdReturn = true;
                chrome.extension.onRequest.addListener(
                    function(request, sender, sendResponse) {
                        if (request.userAgentOverride) {
                            details.requestHeaders[i].value = request.userAgentOverride;
                            holdReturn = false;
                        }
                    });

                chrome.tabs.executeScript(details.tabId,{file: "user-agent-dialog.js"});
                break;
            }
        }

        while (holdReturn) {
            // waiting...
        }

        return {requestHeaders: details.requestHeaders};
     },
  {urls: ["http://*/*"], types: ["main_frame"]},
  ["blocking", "requestHeaders"]);

user-agent-dialog.js文件将具有:

function onFormSubmit() {
    chrome.extension.sendRequest(null, {
        userAgentOverride: userAgentValueFromInput
    });
}

// code to create the dialog and form, this will call
// onFormSubmit() when the form is submitted to send a 
// message back to the background page.