你打开 Chrome 开发者工具,切到 Console 标签页,刚刷新页面,就看到一行红字:Refused to load the script 'https://xxx.com/widget.js' because it violates the following Content Security Policy directive: "script-src 'self'".
别急着关掉——这不是网站崩了,也不是你网络坏了,是浏览器在认真执行一项叫 Content Security Policy(CSP) 的安全规则。就像小区门禁卡只认业主和登记过的访客,CSP 就是给网页定下“谁能进、谁不能进”的白名单。
它为啥突然跳出来?
常见场景:你本地写了个 HTML 文件,双击用 Chrome 打开(注意:不是通过 http://localhost),里面写了 <script src="https://cdn.jsdelivr.net/npm/vue@3.4.0/dist/vue.global.js"></script>,控制台立马报 CSP 错误。因为本地文件走的是 file:// 协议,没有明确的源(origin),浏览器默认启用严格策略,连外部 JS 都不放行。
看懂那条报错信息
拿这句为例:
Refused to load the script 'https://cdn.jsdelivr.net/npm/vue@3.4.0/dist/vue.global.js' because it violates the following Content Security Policy directive: "script-src 'self'".拆开看:
• 想加载的资源:一个远程 Vue 脚本
• 当前策略规定:script-src 'self' —— 只允许同源(也就是当前页面所在域名+端口)的脚本
• 结果:CDN 地址不是同源,被拦下了
怎么临时绕过(仅调试用)
开发时想快速验证功能,可以临时禁用 CSP:
在 Chrome 地址栏输入:
chrome://flags/#unsafely-treat-insecure-origin-as-secure把 Unsafe Web Platform Features 设为 Enabled,再重启浏览器(慎用于生产环境)。
更稳妥的办法:起个本地服务。用 VS Code 安装 Live Server 插件,右键 HTML 文件点 “Open with Live Server”,地址变成 http://127.0.0.1:5500/xxx.html,这时 CSP 规则才有意义,也能按需配置。
真要改策略?加个 meta 标签就行
比如你想允许 CDN 上的 Vue 和 Google Fonts,可以在 HTML 的 <head> 里加:
<meta http-equiv="Content-Security-Policy" content="script-src 'self' https://cdn.jsdelivr.net; font-src https://fonts.googleapis.com;">注意:'self' 带单引号,https://cdn.jsdelivr.net 不带尾部斜杠,多个值用空格分隔。不同资源类型对应不同指令:script-src、style-src、img-src、connect-src……漏写一个,对应资源就可能报错。
顺带一提:如果用了 Nginx 或 Apache,也可以在响应头里加:Content-Security-Policy: script-src 'self' 'unsafe-inline';
但 'unsafe-inline' 是把双刃剑,能解燃眉之急(比如内联 onclick),也降低安全性,上线前建议改用 nonce 或哈希值。
下次再看到 CSP 错误,别第一反应是“又出 bug 了”,先瞄一眼报错里拦的是啥、策略写的是啥——很多时候,它只是太尽职了。