子域名之间设置CORS头时,Access-Control-Allow-Origin该怎么写才不会报错?

Tr° 云辰 阅读 21

我在开发主站example.com时,子域名api.example.com返回的JSON数据总被浏览器拦截,控制台提示:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.example.com/data. (Reason: CORS header 'Access-Control-Allow-Origin' missing).

之前试过在Nginx里这样配置:


server {
    listen 80;
    server_name api.example.com;
    add_header Access-Control-Allow-Origin "*.example.com";
    # 其他配置...
}

但依然不行。后来改成具体域名https://example.com后,控制台又报错说:

Refused to execute script from 'https://api.example.com/data' because its MIME type ('application/json') is not executable, and strict MIME type checking is enabled.

难道子域名之间只能通过通配符配置?但老师说通配符不安全…现在完全不知道该怎么调整CORS头了。

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
极客彩云
这个问题我之前也踩过坑,说起来都是泪。你遇到的两个问题其实都跟CORS头的配置有关,咱们一个一个解决。

首先,关于 Access-Control-Allow-Origin 的值,不能用通配符加域名的形式,比如你写的 "*.example.com" 是无效的。浏览器只认两种情况:要么是具体的域名,比如 https://example.com,要么是 * 表示允许所有域名。但如果你用了 *,就无法同时设置凭据(credentials)相关的头,比如 cookies 或者 authorization headers。

我当时也是折腾了半天才发现,正确的做法是根据请求来源动态设置这个值。在 Nginx 里,可以通过变量来实现。你可以试试下面这种配置:

server {
listen 80;
server_name api.example.com;

# 动态设置 Access-Control-Allow-Origin
set $cors_origin "";
if ($http_origin ~* "^https?://(.*.)?example.com$") {
set $cors_origin $http_origin;
}
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, Authorization" always;

# 如果需要支持跨域凭据
add_header Access-Control-Allow-Credentials "true" always;

# 处理预检请求
if ($request_method = OPTIONS) {
return 204;
}

# 其他配置...
}


这里的关键点是用正则匹配请求来源,并动态设置 $cors_origin 的值。这样既安全又能满足需求。

至于你提到的第二个错误,MIME 类型的问题其实跟你返回的响应内容类型有关,而不是 CORS 配置本身的问题。检查一下你的后端代码或者 Nginx 配置,确保返回 JSON 数据时,头部有明确声明 Content-Type: application/json。如果没设置或者设置错了,浏览器就会报 MIME 类型不匹配的错误。

举个例子,如果你用的是 Nginx 静态文件服务,可以加上类似这样的配置:
default_type application/json;
如果是后端接口,也要确保代码里正确设置了响应头。

总结一下,先用动态方式设置 Access-Control-Allow-Origin,然后检查返回数据的 Content-Type 是否正确。这两个地方搞定,你的问题应该就能解决了。我当时就是这么绕出来的,希望对你有帮助!
点赞 2
2026-02-14 14:06