Nginx中如何允许子域名访问主域名资源?
解决Nginx下跨域JSON加载失败的问题
你遇到的是标准的跨域资源共享(CORS)冲突问题——浏览器的同源策略要求请求来源和资源服务器必须同源(协议、域名、端口一致),而现在http://sub.example.com去请求https://example.com的JSON数据时,服务端返回的Access-Control-Allow-Origin头是固定的https://example.com,和请求来源不匹配,所以被浏览器拦截了。
下面给你两种在Nginx里的解决办法,根据你的需求选择:
方法一:允许所有example.com的子域名(支持http/https)
这种方式最灵活,不管是http://sub.example.com还是https://another.sub.example.com都能正常请求。你需要修改example.com的Nginx服务器配置,在对应的server块里添加以下代码:
# 动态匹配允许的跨域来源(仅限example.com的子域名) set $cors_origin ""; if ($http_origin ~* ^https?://.*\.example\.com$) { set $cors_origin $http_origin; } # 添加CORS响应头 add_header Access-Control-Allow-Origin $cors_origin always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type" always; # 处理OPTIONS预请求(浏览器复杂请求会先发这个) if ($request_method = OPTIONS) { return 204; }
方法二:只允许指定的http://sub.example.com
如果不想开放所有子域名,只想让http://sub.example.com能访问,就用这个配置,同样加在example.com的server块里:
# 固定允许的跨域来源 add_header Access-Control-Allow-Origin "http://sub.example.com" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type" always; # 处理OPTIONS预请求 if ($request_method = OPTIONS) { return 204; }
几个关键注意点:
- 一定要修改example.com的Nginx配置,而不是sub.example.com的——因为是example.com需要对外声明允许哪些域名来请求它的资源。
always参数必须加,否则当example.com返回4xx/5xx错误时,CORS头不会被带上,浏览器还是会报错。- 如果你的请求用到了自定义请求头(比如Authorization)或者其他HTTP方法(比如PUT),要对应修改
Access-Control-Allow-Methods和Access-Control-Allow-Headers的值,把需要的方法和头加进去。 - 配置改完后,记得重启Nginx生效:
sudo nginx -s reload
内容的提问来源于stack exchange,提问作者narad
相关产品推荐
相关产品推荐

