纯静态站点应在Nginx/Apache中用add_header配置CSP,但需显式声明script-src等指令、禁用unsafe-inline/unsafe-eval、处理内联脚本与事件、补全img-src/font-src/connect-src等资源指令,并先通过Report-Only模式收集日志再上线正式策略。

直接在 Nginx 或 Apache 的配置中用 add_header 设置 CSP,对纯静态站点来说是高效且可行的起点,但必须避开常见陷阱——策略太松等于没设,漏关键指令或未处理内联脚本会导致功能异常甚至白屏。
基础策略要收紧,不能只靠 default-src
很多静态站误以为写一句 default-src 'self' 就万事大吉。其实它只兜底未显式声明的指令,一旦页面里有脚本,script-src 必须单独写,否则浏览器按默认宽松行为处理(比如允许 inline)。
-
script-src 'self'是底线:只允许同域 JS,禁掉所有外部和内联执行 - 务必显式禁用危险选项:
script-src 'self' 'unsafe-inline' 'unsafe-eval'这类写法必须删除 - 如果用了 Google Analytics、Clarity 等第三方脚本,得逐个加可信域名,例如:
script-src 'self' https://www.googletagmanager.com https://cdn.jsdelivr.net
内联脚本和事件必须重构或换 nonce
静态 HTML 里常见的 <script>alert(1)</script> 或 <button onclick="doLogin()"></button> 会被 CSP 直接拦截,报错 “Refused to execute inline script”。不能靠开 'unsafe-inline' 来绕过。
- 推荐做法:把内联逻辑抽成外部 JS 文件,用
<script src="/js/main.js"></script>加载 - 若真需保留内联(如某些模板生成器),改用
nonce:后端每次响应生成随机值,同时注入到 HTML 的<script nonce="abc123"></script>和 header 的script-src 'nonce-abc123'中 - 内联事件属性(
onclick,onload)一律改为 JS 事件监听,这是最干净的解法
别漏掉 connect-src、img-src 等关键资源指令
CSP 不只是防脚本,还管资源加载路径。静态站常依赖外部图标、字体、图片或 API(比如搜索框调用 Algolia),这些都得明确放行,否则功能断裂。
-
img-src 'self' data: https:—— 允许同域图、base64 图、所有 HTTPS 图片 -
font-src 'self' https://fonts.gstatic.com—— 若用了 Google Fonts,必须加这条 -
connect-src 'self' https://api.example.com—— AJAX / fetch 请求的目标必须列在这里 -
style-src 'self' 'unsafe-inline'可临时保留(CSS 内联较难剥离),但长期建议转为外部 CSS + hash 或 nonce
上线前先用 Report-Only 模式收集真实拦截
直接上线严格策略风险高。建议先用 Content-Security-Policy-Report-Only 替代 Content-Security-Policy,配合 report-to 或 report-uri 收集浏览器上报的违规日志。
- 在 Nginx 中可这样配(示例):
add_header Content-Security-Policy-Report-Only "default-src 'none'; script-src 'self'; report-to csp-report-endpoint"; - 部署一个简易接收端(如 Express 路由),记录哪些资源被拦、来自哪个页面,再针对性调整策略
- 观察 3–5 天无高频报错,再切到正式
Content-Security-Policy头

















