【发布时间】:2018-01-03 06:32:18
【问题描述】:
我正在用 Javascript 编写一个使用新的 fetch API 的基本应用程序。以下是代码相关部分的基本示例:
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);
}
发出获取请求时,我偶尔会在控制台中看到如下所示的错误:
拒绝加载脚本“
”,因为它违反了以下内容安全策略指令...
在阅读和了解 HTTP/2 之后,似乎会出现此消息,因为响应正在推回预加载的脚本。使用 devtools,我可以在响应中看到以下标题:
链接:;相对=预载; as=脚本
这是我的 Chrome 扩展的 manifest.json 文件的相关部分:
{
"content_security_policy": "script-src 'self'; object-src 'self'"
}
以下是有关 Chrome 的 manifest.json 格式的文档,以及内容安全策略如何应用于扩展程序进行的提取:https://developer.chrome.com/extensions/contentSecurityPolicy
我进行了一些测试,并能够确定此错误消息是在获取期间发生的,而不是稍后在解析响应文本时发生的。脚本元素被加载到实时 DOM 中没有问题,这一切都发生在获取时。
我在研究中找不到的是如何避免这种行为。看起来急于支持这个伟大的新功能,制作 HTTP/2 和 fetch 的人没有考虑我没有获取远程页面以显示它或其任何相关资源(如 css)的用例/图像/脚本。我(应用程序)以后不会使用任何相关资源;只有资源本身的内容。
在我的用例中,此推送 (1) 完全浪费资源,并且 (2) 现在导致控制台中偶尔出现一条非常烦人且会引起压力的消息。
话虽如此,我希望得到一些帮助:有没有办法使用清单或脚本向浏览器发出信号,表明我对 HTTP/2 推送不感兴趣?我可以为获取请求设置一个标头,告诉 Web 服务器不响应推送吗?是否有我可以在我的应用清单中使用的 CSP 设置以某种方式触发 do-not-push-me 响应?
我查看了https://w3c.github.io/preload/ 3.3 节,没有太大帮助。我看到我可以发送像Link: </dont/want/to/push/this>; rel=preload; as=script; nopush 这样的标题。问题是我还不知道响应中将包含哪些 Link 标头,并且我不确定 fetch 是否允许在初始请求中设置 Link 标头。我想知道我是否可以发送某种类型的请求,可以在响应中看到 Link 标头但避免它们,然后发送附加所有适当的 nopush 标头的后续请求?
这是一个重现问题的简单测试用例:
- 获取最新或接近最新的 chrome 开发版
- 创建扩展文件夹
- 创建具有相似 CSP 的清单
- 将扩展加载为解压到 chrome 中
- 在 devtools 中打开扩展的后台页面
- 在控制台中输入 fetch('https://www.yahoo.com')。
- 检查控制台中出现的错误消息:拒绝加载脚本'https://www.yahoo.com/sy/rq/darla/2-9-20/js/gr-min .js',因为它违反了以下内容安全策略指令:“script-src 'self'”。
补充说明:
- 我不想使用代理服务器。一个明确的解释为什么这是我唯一的选择是一个可以接受的答案。
- 我不知道在配置 CSP 时将获取的 url。
- 参见https://www.rfc-editor.org/rfc/rfc7540#section-6.5.1,其中在相关部分声明“SETTINGS_ENABLE_PUSH (0x2):此设置可用于禁用服务器推送(第 8.2 节)。如果端点收到此参数设置为值,则不得发送 PUSH_PROMISE 帧的 0." 有没有办法从脚本或清单中指定此设置,或者将其烘焙到 Chrome 中?
【问题讨论】:
-
为什么你不能只删除响应中的违规标头?
-
@dsign 根据developer.mozilla.org/en-US/docs/Web/API/Response/headers,Response.headers 是只读的。另外,我的理解是,这发生在收到响应时,我的脚本没有时间或地点跳到处理的中间并删除有问题的标头。浏览器处理所有这些。我只能在最后获得访问权限。
-
抱歉不清楚。我的意思是,你为什么不能在服务器端删除有问题的标头?
-
啊。好吧,我无法控制服务器或任何其他服务器。我正在用 javascript 编写一个应用程序,它将获取请求发送到各种其他服务器。甚至没有预先确定或预先编译的列表来说明与哪些其他服务器联系。
-
好吧,我现在明白你的痛苦了。你确定你不会反对普通的CORS protections吗?
标签: javascript google-chrome-extension http2 fetch-api