如何根据 Chrome 扩展中的用户选项修改 http 请求 headers?
How to modify http request headers based on user options in a Chrome extension?
我正在为 Google Chrome 开发我的第一个扩展。我想根据用户可以在我的扩展选项页面上 select 的选项向(所有)http(s) 请求添加自定义 header。
我成功管理了以下内容:
- 手动将自定义 header 添加到所有 http 请求
- 创建选项页面
- 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']);
观察:
- X-Demo-Header2 已正确插入(在 Chrome header 检查和 debigging 控制台中可见)
- x-demo-header1 是 不是 发送到站点的 header 的一部分,但在调试输出中可见
- x-demo-header2在header之前X-Demo-Header1在header控制台中的数组(见屏幕截图)
假设:获取我的选项的函数(项目)是异步执行的,并且在插入我的选项中的 header 之前返回 requestHeaders。
我可以避免这种情况吗?是否有更好的选择根据选项添加headers?
截图:
TL;DR
它目前无法在 Chrome(2021 年 2 月 15 日)
长答案
JavaScript 严重依赖于异步代码执行的思想。在您的代码中,您 return { requestHeaders: details.requestHeaders }
在 chrome.storage.sync.get(key, listener)
中注册的事件侦听器完成之前。因此,demo-header-1
添加得太晚了。
这就是您需要使用 Promise 的原因。 docs 中有一个如何做到这一点的示例。在那个页面向下滚动到它说的地方:“这段代码与前面的例子完全一样,除了侦听器是异步的,returning 一个用新的 [=47= 解析的 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']
);
如您所见,我们现在 return Promise 而不是 object 文字。在这个 Promise 中,我们等待 chrome.storage.sync.get
的读取操作完成。完成后,我们解决 Promise。
这应该适用于支持它的浏览器。
在 Chrome 中这不起作用,因为:
There is no support in Chrome for returning a Promise from webRequest.onBeforeSendHeaders since 2018
除非你能找到一种方法以同步方式从 chrome.storage.sync.get
加载数据,否则恐怕你就不走运了。
作为最后的手段,您可以尝试 post 投诉 Chromium issue。
我正在为 Google Chrome 开发我的第一个扩展。我想根据用户可以在我的扩展选项页面上 select 的选项向(所有)http(s) 请求添加自定义 header。
我成功管理了以下内容:
- 手动将自定义 header 添加到所有 http 请求
- 创建选项页面
- 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']);
观察:
- X-Demo-Header2 已正确插入(在 Chrome header 检查和 debigging 控制台中可见)
- x-demo-header1 是 不是 发送到站点的 header 的一部分,但在调试输出中可见
- x-demo-header2在header之前X-Demo-Header1在header控制台中的数组(见屏幕截图)
假设:获取我的选项的函数(项目)是异步执行的,并且在插入我的选项中的 header 之前返回 requestHeaders。
我可以避免这种情况吗?是否有更好的选择根据选项添加headers?
截图:
TL;DR
它目前无法在 Chrome(2021 年 2 月 15 日)
长答案
JavaScript 严重依赖于异步代码执行的思想。在您的代码中,您 return { requestHeaders: details.requestHeaders }
在 chrome.storage.sync.get(key, listener)
中注册的事件侦听器完成之前。因此,demo-header-1
添加得太晚了。
这就是您需要使用 Promise 的原因。 docs 中有一个如何做到这一点的示例。在那个页面向下滚动到它说的地方:“这段代码与前面的例子完全一样,除了侦听器是异步的,returning 一个用新的 [=47= 解析的 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']
);
如您所见,我们现在 return Promise 而不是 object 文字。在这个 Promise 中,我们等待 chrome.storage.sync.get
的读取操作完成。完成后,我们解决 Promise。
这应该适用于支持它的浏览器。
在 Chrome 中这不起作用,因为:
There is no support in Chrome for returning a Promise from webRequest.onBeforeSendHeaders since 2018
除非你能找到一种方法以同步方式从 chrome.storage.sync.get
加载数据,否则恐怕你就不走运了。
作为最后的手段,您可以尝试 post 投诉 Chromium issue。