Nginx 配置 CORS 必须覆盖 API 路径,否则 preload(as="fetch")会因缺少 Access-Control-Allow-Origin 等头而失败;prefetch 默认不触发 CORS 检查,但后续 fetch 读取仍需合法 CORS 响应。

在 Nginx 中配置 API 跨域(CORS)时,不会直接影响浏览器的 preload 或 prefetch 行为本身,但会影响它们是否能成功加载资源——尤其是当预加载的目标是跨域 API 接口(如 JSON 数据、GraphQL 端点)时。
Preload/Prefetch 本身不触发 CORS 检查
preload 和 prefetch 是资源提示(resource hints),用于提前获取资源,但它们的执行机制不同:
-
<link rel="preload" as="fetch">:明确声明将用于fetch(),此时浏览器会发起带 CORS 的请求,必须满足目标服务器返回合法 CORS 响应头(如Access-Control-Allow-Origin); -
<link rel="prefetch">:默认以as="document"处理,若未指定as或指向非脚本/样式类资源(如 API JSON),浏览器通常按普通导航或无 CORS 模式处理,不强制校验 CORS —— 但后续 JavaScript 若用fetch()读取该缓存,仍需 CORS 合法性; - 如果
prefetch显式写成as="fetch"或指向application/json类型且被 JS 主动读取,同样触发 CORS 检查。
Nginx CORS 配置需覆盖预加载路径
若你用 preload 加载跨域 API(例如 /api/v1/data),Nginx 必须对该路径返回正确的 CORS 头。常见疏漏是:
- CORS 规则只配在主页面 location,未覆盖 API 接口路径;
- 使用了
if ($request_method = 'OPTIONS')但未在对应 API location 块中启用; - 未设置
Access-Control-Allow-Credentials: true(当预加载请求带 cookie 时必需); - 遗漏
Access-Control-Expose-Headers(若 JS 需读取自定义响应头,如X-RateLimit-Remaining)。
推荐 Nginx 配置片段(API 路径专用)
针对 /api/ 下所有接口,建议在对应 location 块中统一添加:
location /api/ {
# 允许指定源或 *
add_header 'Access-Control-Allow-Origin' 'https://your-app.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
<pre class="brush:php;toolbar:false;"># 处理预检请求
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 17280000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# 正常代理到后端
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;}
调试建议:确认预加载是否真正生效
仅靠 Network 面板看“prefetch”条目不等于资源可用。验证方法:
- 打开 DevTools → Network → Filter 输入
is:prefetch(Chrome)或查看 Initiator 列是否为preload/prefetch; - 检查该请求的 Response Headers 是否含完整 CORS 头(特别是
Access-Control-Allow-Origin); - 在控制台执行
fetch('/api/test').then(r => r.json()),观察是否报 CORS 错误——这反映预加载后 JS 使用时的真实限制; - 注意:Chrome 对
prefetch有启发式策略(如空闲、高内存、低带宽下可能跳过),不可强依赖其必然执行。
不复杂但容易忽略:跨域预加载能否走通,关键不在 HTML 标签怎么写,而在 Nginx 是否把对应 API 路径当作“可被前端脚本安全读取的资源”来响应。

















