繁体   English   中英

如何根据 Chrome 扩展中的用户选项修改 http 请求标头?

[英]How to modify http request headers based on user options in a Chrome extension?

我正在为 Google Chrome 开发我的第一个扩展程序。 我想根据用户可以在我的扩展程序的选项页面上 select 的选项将自定义 header 添加到(所有)http(s)请求。

我成功地管理了以下内容:

  1. 手动将自定义标头添加到所有 http 请求
  2. 创建选项页面
  3. chrome.storage.sync 中的保存和恢复选项

现在我正在努力将上述内容结合起来。 这是我尝试过的:

chrome.webRequest.onBeforeSendHeaders.addListener(function(details){
    var demoOptions = new Array();
    var demoHeader = '';
    var bkg = chrome.extension.getBackgroundPage(); // for debugging
    chrome.storage.sync.get({
    demoOption: true,
    }, function(items) {
        if(items.demoOption){
            demoOptions.push('demo-header-1');
        }
        demoHeader = demoOptions.join();
        details.requestHeaders.push({
            name: 'X-Demo-Header',
            value: demoHeader //this is not showing up in the http headers
        });
        bkg.console.log('demoHeader:' + demoHeader); //this is putting the correct value to the debugging console
        bkg.console.log(details.requestHeaders); //this is putting the headers to the debugging console, incl. x-demo-header1 and x-demo-header2 (see below)
    });

    details.requestHeaders.push({
        name: 'X-Demo-Header2',
        value: 'Demo-Header-2' //this is correctly added to the headers and included in the request
    });
    
    return { requestHeaders: details.requestHeaders };
},
{urls: [ "*://*/*" ]},['requestHeaders','blocking']);

观察:

  1. X-Demo-Header2 已正确插入(在 Chrome header 检查和调试控制台中可见)
  2. x-demo-header1不是发到本站的 header 的一部分,但是在调试中可以看到 output
  3. x-demo-header2 位于控制台中 header 数组中的 X-Demo-Header1之前的 header 中(参见屏幕截图)

假设:获取我的选项的函数(项目)是异步执行的,并且 requestHeaders 在插入我的选项的标头之前返回。

我可以避免这种情况吗? 有没有更好的选择来根据选项添加标题?

截屏:

头数组的调试输出

TL;博士

它目前无法在 Chrome 中运行(2021 年 2 月 15 日)

长答案

JavaScript 严重依赖异步代码执行的思想。 在您的代码中,您在chrome.storage.sync.get(key, listener)中注册的事件侦听器完成之前返回{ requestHeaders: details.requestHeaders } 因此, demo-header-1添加得太晚了。

这就是您需要使用 Promise 的原因。 文档中有一个示例如何做到这一点。 在该页面上向下滚动到它显示的位置: “此代码与前面的示例完全相同,除了侦听器是异步的,返回一个 Promise ,它使用新的标头解析”

在您的情况下,修改后的代码版本如下所示:

chrome.webRequest.onBeforeSendHeaders.addListener(
  function (details) {
    return new Promise((resolve, reject) => {
      chrome.storage.sync.get({ demoOption: true }, function (items) {
        if (items.demoOption) {
          details.requestHeaders.push({
            name: 'X-Demo-Header',
            value: 'demo-header-1',
          });
        }
        resolve({ requestHeaders: details.requestHeaders });
      });
    });
  },
  { urls: ['*://*/*'] },
  ['blocking', 'requestHeaders']
);

如您所见,我们现在返回 Promise 而不是 object 文字。 在这个 Promise 中,我们等待chrome.storage.sync.get的读取操作完成。 完成后,我们解析 Promise。

这应该在支持它的浏览器中工作。

在 Chrome 中这不起作用,因为:

自 2018 年以来,Chrome 不支持从 webRequest.onBeforeSendHeaders 返回 Promise

除非您能找到一种以同步方式从chrome.storage.sync.get加载数据的方法,否则恐怕您很不走运。

作为最后的手段,您可以尝试在该Chromium 问题中发布投诉。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM