要让cdn或子域名顺利加载静态资源,关键是精准匹配路径、配置带always的cors头、显式处理options预检、并返回强缓存头确保cdn透传。

静态资源要让 CDN 或子域名(如 cdn.example.com、app.example.com)顺利加载,关键不是加几个头就完事,而是头要准、路径要窄、预检要稳、缓存要可信。Nginx 本身不控制第三方 CDN 的响应头,所以这里说的“方便 CDN 加载”,是指你自己的 Nginx 作为源站时,为静态资源配好 CORS,让 CDN 回源后能正确缓存并透传这些头,同时确保子域名前端也能安全读取 JS、字体等资源。
精准匹配静态资源路径,避免污染其他接口
不要在 server 或 http 块里全局加 CORS 头,否则 API 接口、管理后台也可能被暴露。推荐用正则只作用于真实静态文件:
- 匹配常见后缀:用
location ~* \.(js|css|png|jpg|gif|woff2|ttf|eot|svg|ico)$,务必包含.woff2和.ttf——字体在 file:// 或子域名下也触发 CORS 校验 - 若资源统一放在
/static/目录下,可用location /static/ { }更简洁,但需确认构建输出路径一致 - 避免用
location / { }这类宽泛匹配,防止把/api/login也带上 CORS 头
配置带 always 的完整 CORS 响应头
静态资源通常只读、不传 Cookie,所以可安全使用通配符或指定多个子域名,但必须加 always,否则 304、404 等状态码会丢失头:
-
add_header 'Access-Control-Allow-Origin' 'https://app.example.com' always;—— 推荐写具体子域名;若需支持多个,用map变量动态匹配 -
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;—— 静态资源不需要 POST/PUT add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;-
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;—— 对字体断点续传和分片加载很关键
显式响应 OPTIONS 预检请求
浏览器加载带自定义 header 的 JS、字体或发起 fetch 请求前,会先发 OPTIONS。Nginx 默认不处理,直接返回空或 502,导致跨域失败:
- 在同一个
location块内加:if ($request_method = 'OPTIONS') { } - 里面重复写关键头(Origin、Methods、Headers),同样带
always - 加上
add_header 'Content-Length' 0;和add_header 'Content-Type' 'text/plain; charset=utf-8'; - 结尾必须是
return 204;,返回空响应体
配合 CDN 缓存策略,确保头能被正确回源与透传
CDN 要缓存并转发你的 CORS 头,Nginx 必须返回强缓存标识,且不能被防盗链或限速规则拦截:
- 加缓存头:
add_header Cache-Control "public, immutable, max-age=31536000";+expires 1y; - 检查是否启用了
referer防盗链,若 CDN 回源请求无 referer,需放行(例如:valid_referers none server_names;) - 禁用对静态资源的
limit_req或deny all,避免预热或 CDN 批量拉取时被限速或拒绝 - 验证 CDN 是否透传:用
curl -I https://cdn.example.com/app.js查看响应中是否含Access-Control-Allow-Origin











