前端调接口,浏览器 Console 一片红:
Access to XMLHttpRequest at 'https://api.wuxiannet.com/blog/list'
from origin 'https://blog.wuxiannet.com' has been blocked by CORS policy:
The 'Access-Control-Allow-Origin' header contains multiple values '*, *',
but only one is allowed.
两个 *。问题出在哪?
排查过程
后端 Spring Boot 配了 CORS:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("*")
.allowedHeaders("*");
}
}
同时 Nginx 也加了:
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Headers *;
每一层各加了一次 CORS 头。 浏览器收到了两个 Access-Control-Allow-Origin: *,直接拒收。
CORS 规范规定:Access-Control-Allow-Origin 只能有一个值。多个值浏览器认为响应不合法,请求被拦截。
正确做法:只让一处加
Spring Boot 和 Nginx,二选一。推荐 Nginx 层统一处理:
# ✅ Nginx 统一 CORS,Spring 删掉 CorsConfig
location /api/ {
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
add_header Access-Control-Allow-Headers 'Authorization, Content-Type';
add_header Access-Control-Max-Age 86400;
return 204;
}
add_header Access-Control-Allow-Origin $http_origin;
proxy_pass http://127.0.0.1:8083;
}
$http_origin 是 Nginx 变量,取请求头里的 Origin。不用 * 是因为 CORS 规范里 * 和 credentials: true 不兼容。
如果必须用 Spring 配,就删 Nginx 的 CORS 配置,确保只有一处产出。
CORS 的本质
跨域请求不是禁止,是需要服务器明确允许。浏览器发请求前会先发一个 OPTIONS 预检请求(Preflight),问服务器:「我能跨域调你吗?」
服务器返回 CORS 头后,浏览器判断是否匹配。不匹配或头有错误,请求都不会发出。
常见的 CORS 错误不止双重头:
| 两个 Access-Control-Allow-Origin | 多层加了 CORS(Nginx + Spring) |
| Origin not allowed | allowedOrigins 没包含请求来源 |
| Credentials 报错 | 用了 * 但前端传了 withCredentials |
| OPTIONS 返回 403 | 没处理预检请求 |
CORS 报错不是莫名奇妙的。打开 Network 看 OPTIONS 响应头,逐个对比你的 CORS 配置,定位很快。
多层加 CORS 是典型的「各管各」问题——Nginx 觉得自己该加,Spring 也觉得自己该加。结果是两个人都加了,浏览器不认。
谁在最外层,谁管 CORS。 内部别插手。
关于作者:无羡,独立开发者,全栈工程师,专注 AI 应用与微服务架构。
📌 分类:独立开发实战
🔗 个人博客 — 更多技术文章 ✨ 开发者福利整理 — 云服务资源汇总 📂 软件工坊 — 我的技术分享 🌐 个人门户 — 独立开发作品全集



