你在调试网页时,突然发现一张轮播图没显示,或者按钮点击没反应,打开 Chrome 控制台一看,顶部刷出一行红字:Refused to load the image 'https://xxx.com/logo.png' because it violates the following Content Security Policy directive: "img-src 'self'".
CSP不是“锅”,是门禁系统
Content Security Policy(CSP)不是 bug,它是浏览器主动帮你加的一道安全门禁。就像公司前台只放行工牌+预约访客,CSP 告诉 Chrome:“只准从这些地方加载图片、运行这些来源的脚本、连接这些域名的接口。”一旦资源不符合规则,Chrome 就默默拒之门外,并在控制台记一笔——这就是你看到的 CSP 错误。
常见报错长啥样?
比如你在页面里写了:
<script src="https://cdn.jsdelivr.net/npm/vue@3.4.0/dist/vue.global.js"></script>但响应头里设置了:Content-Security-Policy: script-src 'self'Chrome 就会报:Refused to load script from 'https://cdn.jsdelivr.net/...' because it violates the script-src directive.再比如用 fetch 请求了外域 API:
fetch('https://api.example.com/data')而 CSP 是 connect-src 'self',控制台就会提示连接被拒绝。怎么快速定位问题?
直接看控制台报错里的两个关键信息:
1)Refused to load the [resource type] —— 被拦的是图片、脚本、样式还是字体?
2)because it violates ... directive: "xxx-src ..." —— 看清是哪个指令(img-src、script-src、style-src、connect-src 等)不满足。
然后对照你页面实际加载的资源地址,和响应头或 <meta> 标签中设置的 CSP 规则,一一对比。例如:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; img-src 'self' data:">说明脚本只能来自当前域名,图片只能来自当前域名或 data: 协议(比如 base64 图片),引入 CDN 的 JS 或外链图片自然失败。本地开发常踩的坑
用 file:// 协议直接双击打开 HTML 文件?CSP 会失效——但别高兴太早。很多现代框架(如 Vite)默认启用 CSP 兼容模式,且 Chrome 对 file:// 下的内联脚本(<script>alert(1)</script>)也会拦截,报 unsafe-inline 相关错误。这时候得在 CSP 里加上 'unsafe-inline'(仅限本地调试,上线千万别留!)。
另外,Vue/React 开发时热更新注入的脚本、Chrome 插件注入的代码,也可能触发 CSP 报错。可以临时在命令行启动 Chrome 时加参数绕过:chrome.exe --user-data-dir=/tmp/csp-test --unsafely-treat-insecure-origin-as-secure="http://localhost:5173" --user-agent="dev",但这是权宜之计,根源还得调 CSP 规则。