为什么设置了CSP后图片和字体资源还是被阻止了?
我在开发博客项目时配置了CSP头,但图片和字体资源还是被浏览器拦截了。我明明设置了和,控制台报错显示:
Refused to load the image 'https://images.example.com/pic.jpg' because it violates the following Content Security Policy directive: "img-src https://fonts.example.com".
我的配置是这样写的:
Content-Security-Policy: default-src 'self'; img-src https://images.example.com; font-src https://fonts.example.com;
已经确认域名拼写正确,但为什么字体源会出现在图片的错误信息里?尝试过添加nonce和星号通配符都没用,求指点哪里配置错了
img-src和font-src,但没给default-src留后门,浏览器会用default-src的值作为 fallback 去匹配图片资源。你现在的策略是:
default-src 'self',意味着所有没显式声明的资源类型都只能加载同源资源。而img-src虽然写了https://images.example.com,但问题出在——default-src和img-src是并列关系,不是覆盖关系,浏览器会优先用img-src,但如果你的图片 URL 实际上走的是https://协议,而你img-src里只写了域名没带协议,某些浏览器会误判匹配失败。不过更可能的原因是:你截图里报错说
Refused to load the image ... because it violates ... "img-src https://fonts.example.com",这明显是 CSP 策略里写错了——你贴出来的配置里img-src是https://images.example.com,但报错里却显示img-src https://fonts.example.com,说明你实际响应头里可能写的是img-src https://fonts.example.com,而不是你帖子里写的那个。建议改成这样:
Content-Security-Policy: default-src 'self'; img-src 'self' https://images.example.com; font-src 'self' https://fonts.example.com;注意几点:
-
img-src和font-src都补上'self',避免本地资源被拦- 确保响应头里实际发送的字符串和你测试时写的完全一致(别复制粘贴漏了空格或写错域名)
- 如果用了 CDN 或反向代理,确认 CSP 头确实被加到了最终响应里,而不是被中间层改写了
最后查一查浏览器开发者工具的 Network 标签,看响应头里
Content-Security-Policy的值到底是什么——经常是本地调试时改了代码但忘了重启服务,浏览器还在用旧的 CSP 缓存。img-src https://images.example.com和font-src https://fonts.example.com没有问题,但default-src 'self'会影响其他未明确指定的资源类型。图片被拦截的原因是,虽然你设置了
img-src,但字体资源的加载规则继承了default-src 'self',而字体域名https://fonts.example.com不在default-src的范围内。这导致字体加载失败,进一步影响了图片资源的解析。解决办法很简单,改一下就行:
这里加了
style-src是因为字体通常通过CSS加载,如果CSS本身被拦截,字体也加载不了。另外,确认一下页面上的图片和字体请求是否真的匹配了你设置的域名,有时候路径或者协议(http/https)不一致也会导致问题。最后提醒一句,调试CSP的时候打开浏览器的开发者工具看网络请求和控制台报错,能省不少时间。