Nginx中需按资源类型协同配置安全响应头与强缓存:静态资源启用30天强缓存(public, immutable)并保留X-Content-Type-Options等轻量安全头;HTML页面禁用缓存(no-store)并启用完整安全头;API接口禁用缓存并强化CSP、X-Frame-Options等防护。

直接在 Nginx 中配置安全响应头 + 强缓存,不是简单堆叠参数,而是让两者协同工作:安全头保护资源不被滥用,强缓存减少重复传输。关键在于不冲突、不覆盖、分场景设置——静态资源用强缓存+最小化安全头,动态接口禁用缓存+强化防护。
一、区分资源类型,按需配置缓存与安全头
强缓存(Expires / Cache-Control)和安全头(如 X-Content-Type-Options)可共存,但必须避免逻辑矛盾。例如:对 JS/CSS/图片等静态资源启用强缓存,同时保留必要安全头;对 API 接口或登录页则禁用缓存,并启用全部防护头。
- 静态资源(/static/、/images/、/js/ 等):启用 30 天强缓存,仅保留防 MIME 嗅探、防 iframe 嵌套等轻量级安全头
-
HTML 页面(/、/login、/admin 等):禁用缓存(
no-store),启用完整安全头(CSP、XSS 防护、Referrer 控制等) -
API 接口(/api/):默认不缓存(
no-cache或private),重点加Content-Security-Policy和X-Frame-Options
二、静态资源强缓存 + 安全头示例配置
以下配置放在 location 块中,作用于静态目录,兼顾性能与基础防护:
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2|ttf)$ {
expires 30d;
add_header Cache-Control "public, immutable";
<pre class="brush:php;toolbar:false;"># 必须保留的安全头(不影响缓存)
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options "DENY";
add_header Referrer-Policy "no-referrer-when-downgrade";
# 不加 X-XSS-Protection 和 CSP(现代浏览器已弃用/不兼容强缓存策略)}
注意:immutable 是关键——它告诉浏览器“此资源绝不会变”,允许跳过协商缓存(If-None-Match),真正实现“一次加载,长期复用”。
三、HTML 页面禁用缓存 + 全面安全头配置
对 HTML 文件,缓存必须让位于安全性。以下配置确保每次访问都校验服务端状态,同时阻断常见攻击面:
location / {
# 禁用所有缓存(含代理和浏览器)
add_header Cache-Control "no-store, must-revalidate, max-age=0";
add_header Expires "0";
<pre class="brush:php;toolbar:false;"># 完整安全头组合
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline'; img-src 'self' data:;";}
其中 no-store 是最严格指令,强制浏览器不保存副本;Content-Security-Policy 按实际资源来源微调,避免因策略过严导致页面功能异常。
四、验证是否生效且无冲突
配置后务必通过工具验证两方面是否协同正常:
- 用
curl -I https://yourdomain.com/static/main.js检查是否同时返回Cache-Control: public, immutable和X-Content-Type-Options: nosniff - 用浏览器开发者工具 → Network → 查看 HTML 请求的响应头,确认
Cache-Control为no-store,且所有安全头存在且值正确 - 打开
application/cache面板,确认 JS/CSS 显示(from memory cache),而 HTML 始终是200(非缓存)











