如何解决如何使用Webpack,内容安全策略以及对自己的服务器和外部站点的提取/ ajax调用?
fetch('https://ipinfo.io/json')
.then(response => response.json())
.then(data => console.log(data));
我的webpack构建很好,直到我添加了它,然后我开始遇到有关内容安全政策的错误。
以前,我没有定义任何内容安全策略。
我已经尝试了几种解决错误的方法(请参阅文章结尾),最新方法是将其添加到index.html文件的开头部分:
<Meta http-equiv="Content-Security-Policy" content="script-src 'self'; connect-src https://ipinfo.io/json">
现在,我在Chrome开发者工具控制台中遇到了这些错误,它们似乎相互矛盾:
错误#1-与jquery ajax获取对我自己的api的请求
bundle.js:25 Refused to connect to 'http://localhost:3000/api/v1/resource?parameter=false&_=1598715905517' because it violates the following Content Security Policy directive: "connect-src https://ipinfo.io/json".
bundle.js:1 Refused to connect to 'https://ipinfo.io/json' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'connect-src' was not explicitly set,so 'default-src' is used as a fallback.
注意:第二个错误表明未明确设置connect-src
,但是发生第一个错误是因为它已明确设置。
bundle.js:1 Refused to connect to 'https://ipinfo.io/json' because it violates the document's Content Security Policy.
bundle.js:1
Uncaught (in promise) TypeError: Failed to fetch
at HTMLDocument.<anonymous> (bundle.js:1)
at u (bundle.js:25)
at l (bundle.js:25)
其他方法
作为参考,这是我尝试使用nonce
的其他方法之一:
我将此添加到了entry.js
:
__webpack_nonce__ = 'something-tricky';
这是索引文件的<head>
部分:
<Meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-something-tricky';
结果是它不会加载bundle.js
:
Refused to load the script 'http://localhost:3000/js/bundle.js' because it violates the following Content Security Policy directive: "script-src 'nonce-something-tricky'". Note that 'script-src-elem' was not explicitly set,so 'script-src' is used as a fallback.
此方法基于:
https://webpack.js.org/guides/csp
https://stackoverflow.com/a/42924000
更多上下文
当我开始在<head>
部分尝试各种CSP组合时,我注意到它开始破坏很多东西,例如:
因此,我意识到有必要完全正确地使用CSP,否则它将根本无法正常工作。
我最后的尝试是这样
<Meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://ipinfo.io; style-src 'self' fonts.googleapis.com 'unsafe-inline'; font-src 'self' fonts.gstatic.com">
我收到此错误:
bundle.js:25 Refused to load the script 'https://ipinfo.io/json?callback=jQuery35106635073412967416_1598793439782&_=1598793439783' because it violates the following Content Security Policy directive: "script-src 'self'". Note that 'script-src-elem' was not explicitly set,so 'script-src' is used as a fallback.
$.get("https://ipinfo.io/json",function(response) {
console.log(response);
},"jsonp");
最后一个错误很奇怪,因为它似乎是忽略我在srcipt-src
指令中特别“列入白名单”的域。
解决方法
好吧,好吧,我在Chrome开发人员工具的Network
标签中查看了其他请求,并看到Response Headers
标签中应用了相当丰富的CSP指令集,但我没有设置他们,所以我想知道它们来自哪里。
我碰到了this answer,其中提到可以使用helmet in node设置它们
因此在我的节点应用程序中,我替换了:
app.use(helmet());
具有:
app.use(
helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],scriptSrc: ["'self'","https://ipinfo.io"],styleSrc: ["'self'","fonts.googleapis.com","'unsafe-inline'"],fontSrc: ["'self'","fonts.gstatic.com"]
}
},})
);
现在来自entry.js
的请求正在运行:
$.get("https://ipinfo.io/json",function(response) {
console.log(response);
},"jsonp");
请注意,我必须在unsafe-inline
上添加StyleSrc
,否则使用webpack导入并捆绑到bundle.js
的CSS将无法正常工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。