Jos*_*osh 25 javascript google-chrome-extension http2 fetch-api
我正在使用新的fetch API在Javascript中编写一个基本应用程序.以下是代码相关部分的基本示例:
function foo(url) {
const options = {};
options.credentials = 'omit';
options.method = 'get';
options.headers = {'Accept': 'text/html'};
options.mode = 'cors';
options.cache = 'default';
options.redirect = 'follow';
options.referrer = 'no-referrer';
options.referrerPolicy = 'no-referrer';
return fetch(url, options);
}
Run Code Online (Sandbox Code Playgroud)
在进行获取请求时,我偶尔会在控制台中看到如下所示的错误:
拒绝加载脚本'<url>',因为它违反了以下内容安全策略指令...
在阅读并了解HTTP/2之后,看起来会出现此消息,因为响应正在推回预加载的脚本.使用devtools,我可以在响应中看到以下标题:
链接:<路径到脚本>; 相对=预载荷; 为=脚本
以下是我的Chrome扩展程序manifest.json文件的相关部分:
{
"content_security_policy": "script-src 'self'; object-src 'self'"
}
Run Code Online (Sandbox Code Playgroud)
以下是Chrome的manifest.json格式的文档,以及内容安全策略如何应用于扩展程序提取的内容:https://developer.chrome.com/extensions/contentSecurityPolicy
我做了一些测试,并且能够确定在获取期间发生此错误消息,而不是在解析响应文本时.没有问题将脚本元素加载到实时DOM中,这一切都发生在获取时.
在我的研究中我无法找到的是如何避免这种行为.看起来急于支持这个伟大的新功能,制作HTTP/2和fetch的人没有考虑我没有获取远程页面以便显示它或其任何相关资源(如css)的用例/图像/脚本.我(应用程序)以后不会使用任何相关资源; 只有资源本身的内容.
在我的使用案例中,这种推送(1)完全浪费了资源,并且(2)现在导致一个非常恼人和压力诱导的消息偶尔出现在控制台中.
话虽如此,这是我希望得到一些帮助的问题:有没有办法向浏览器发信号,使用清单或脚本,我对HTTP/2推送不感兴趣?是否有我可以为获取请求设置的标头告诉Web服务器不响应推送?我可以在我的应用程序清单中使用CSP设置,以某种方式触发不要推送我的响应吗?
我查看了https://w3c.github.io/preload/第3.3节,它没有多大帮助.我看到我可以发送标题Link: </dont/want/to/push/this>; rel=preload; as=script; nopush.问题是我还不知道响应中会有哪些链接头,我不确定fetch是否允许在初始请求中设置链接头.我想知道我是否可以发送某些类型的请求,可以在响应中看到链接头但是避免它们,然后发送追加所有相应nopush头的后续请求?
这是一个简单的测试用例来重现这个问题:
补充说明:
在跟随您的测试用例之后,我能够以下列方式解决此问题(示例),但我不知道它适用于所有更一般的情况:
chrome.webRequest拦截对扩展的请求的响应.onHeadersRecieved去除包含的标题rel=preload我不得不承认我花了很多时间试图弄清楚为什么这似乎有效,因为我不认为剥离链接头应该适用于所有情况.我认为Server Push会在发送请求后才开始推送文件.
正如您在附加说明中所提到的,其中SETTINGS_ENABLE_PUSH大部分内容实际上已经融入了Chrome并且隐藏在我们的视图中.如果你想深入挖掘,我发现了详细信息chrome://net-internals/#http2.也许Chrome会杀死Server Push发送的文件,这些文件在初始响应中没有相应的链接头.
这个解决方案取决于chrome.webRequest Docs
扩展程序的后台脚本:
let trackedUrl;
function foo(url) {
trackedUrl = url;
const options = {};
options.credentials = 'omit';
options.method = 'get';
options.headers = { 'Accept': 'text/html' };
options.mode = 'cors';
options.cache = 'default';
options.redirect = 'follow';
options.referrer = 'no-referrer';
options.referrerPolicy = 'no-referrer';
return fetch(url, options)
}
chrome.webRequest.onHeadersReceived.addListener(function (details) {
let newHeaders;
if (details.url.indexOf(trackedUrl) > -1) {
newHeaders = details.responseHeaders.filter(header => {
return header.value.indexOf('rel=preload') < 0;
})
}
return { responseHeaders: newHeaders };
}, { urls: ['<all_urls>'] }, ['responseHeaders', 'blocking']);
Run Code Online (Sandbox Code Playgroud)
扩展的清单:
{
"manifest_version": 2,
"name": "Example",
"description": "WebRequest Blocking",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png"
},
"background": {
"scripts": [
"back.js"
]
},
"content_security_policy": "script-src 'self'; object-src 'self'",
"permissions": [
"<all_urls>",
"background",
"webRequest",
"webRequestBlocking"
]
}
Run Code Online (Sandbox Code Playgroud)
补充说明:
我只是天真地将这个限制到扩展的最新请求网址,有 webRequest.requestFilters烤到chrome.webRequest你可以在这里查看
您可能还希望更加具体地了解您删除哪些标头.我觉得剥离所有的链接都会有一些额外的效果.
这避免了代理,并且不需要在请求中设置链接头.
这是一个非常强大的扩展,我个人避免使用权限扩展<all_urls>,希望你可以缩小范围.
我没有测试阻止删除标头响应导致的延迟.
| 归档时间: |
|
| 查看次数: |
812 次 |
| 最近记录: |