Nginx可同时支持CORS与缓存,需手动配置Access-Control-Allow-Origin等CORS头,并用Cache-Control控制缓存;关键是要在proxy_cache_key中包含$http_origin、add_header Vary "Origin",避免跨域策略污染。

要让Nginx同时支持API接口的跨域(CORS)与缓存控制(如Expires),关键不是“协同”两个功能,而是按HTTP规范合理设置响应头:CORS头决定浏览器是否允许前端访问响应,缓存头(如Expires、Cache-Control)决定该响应能否被复用。二者互不冲突,可共存,但需注意顺序和语义一致性。
正确配置CORS响应头
Nginx本身不内置CORS逻辑,需手动添加响应头。对API接口,至少需提供以下基础头:
-
Access-Control-Allow-Origin:指定允许跨域的源。生产环境避免设为
*(尤其当请求含凭据时);可动态匹配白名单,例如使用map模块映射可信域名 -
Access-Control-Allow-Methods:明确列出允许的HTTP方法,如
GET, POST, OPTIONS -
Access-Control-Allow-Headers:声明允许客户端发送的自定义请求头,如
Authorization, X-Request-ID -
Access-Control-Allow-Credentials:若前端设置了
credentials: 'include',此项必须为true,且Access-Control-Allow-Origin不能为* - 对预检请求(OPTIONS),应返回204并仅含CORS头,不触发后端业务逻辑
合理设置缓存头(Expires + Cache-Control)
API接口缓存需谨慎:非幂等、带用户上下文或实时性要求高的接口不宜缓存。适合缓存的场景如公开的静态配置、字典数据、只读列表等。Nginx中推荐优先使用Cache-Control,它比Expires更灵活、更符合现代实践:
- 用
add_header Cache-Control "public, max-age=3600";表示该响应可被浏览器和中间代理缓存1小时 - 若仍需兼容老系统,再补充
add_header Expires ...,值为GMT格式时间戳(可用$upstream_http_expires变量或set配合lua/ngx_time) - 避免对POST/PUT/DELETE等非安全方法设置缓存头;对GET请求,确保后端响应本身是可缓存的(如无Set-Cookie、Vary:*等冲突头)
- 注意:Nginx默认不缓存带有Set-Cookie的响应,也不缓存Vary头值为*的响应——这些会自动绕过proxy_cache
让CORS与缓存头在Nginx中安全共存
核心原则是:所有影响缓存决策的响应头(包括CORS头)都应纳入缓存键(cache key)考量,否则可能造成跨域策略污染或缓存混淆。例如:
- 若不同Origin请求同一URL,但Nginx缓存未将
Origin或Access-Control-Allow-Origin纳入key,则可能把A站的CORS响应错返回给B站,导致安全问题 - 解决方案:在
proxy_cache_key中显式包含$http_origin,并在add_header Access-Control-Allow-Origin $http_origin;实现动态回写(前提是Origin在白名单内) - 同时,在
proxy_hide_header中不要隐藏Access-Control-Allow-Origin等关键CORS头,否则缓存响应将缺失它们 - 建议启用
add_header Vary "Origin";,显式告知下游(浏览器/CDN)该响应根据Origin变化,增强缓存隔离性
一个典型Nginx配置片段
以下适用于只读JSON API,启用缓存并支持可信来源跨域:
map $http_origin $cors_origin {
default "";
"~^https?://(localhost|myapp\.com|api\.trusted\.site)$" $http_origin;
}
<p>server {
location /api/v1/config {
proxy_pass <a href="https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e">https://www.php.cn/link/65b5b8d1f89bf53a5713bc3afdd83e9e</a>;
proxy_cache my_cache;
proxy_cache_valid 200 3600s;</p><pre class="brush:php;toolbar:false;"> # 缓存键包含Origin,避免CORS头混用
proxy_cache_key "$scheme$request_method$host$request_uri$http_origin";
# 动态设置CORS头
add_header Access-Control-Allow-Origin $cors_origin;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Authorization, X-Requested-With";
add_header Access-Control-Allow-Credentials "true";
add_header Vary "Origin";
# 缓存控制(优先Cache-Control)
add_header Cache-Control "public, max-age=3600";
# 可选:补Expires(需计算GMT时间,此处略)
# 处理预检
if ($request_method = 'OPTIONS') {
add_header Access-Control-Max-Age 1728000;
add_header Content-Type 'text/plain; charset=UTF-8';
add_header Content-Length 0;
return 204;
}
}
}
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











