TW

// post

前后端分离项目的跨域问题,一次讲清

CORS 报错信息往往很模糊。本文从浏览器的同源策略出发,讲清预检请求、凭证携带与生产环境的正确配置方式。

2026.07.02·3 min read·986 views

跨域不是后端"不让你访问"

先纠正一个常见误解:跨域限制是浏览器施加的,服务端其实收到了请求。这也是为什么 Postman 测得好好的,浏览器里却报错。

同源的定义

协议、域名、端口三者完全相同才算同源。

http://localhost:5173  →  http://localhost:8080   ✗ 端口不同
https://a.com          →  http://a.com            ✗ 协议不同
https://a.com          →  https://api.a.com       ✗ 域名不同

简单请求与预检请求

触发预检(OPTIONS)的条件之一是"非简单请求":自定义请求头(比如带上 Authorization)、Content-Type 为 application/json,都会触发预检。

服务端需要正确响应 OPTIONS:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOriginPatterns("http://localhost:*")   // 开发环境
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);        // 预检结果缓存 1 小时,减少 OPTIONS 请求
    }
}

携带凭证时的两个硬性要求

如果你要在请求中带 Cookie(withCredentials = true):

  1. Access-Control-Allow-Origin 不能为 *,必须明确指定来源
  2. 必须同时返回 Access-Control-Allow-Credentials: true

这也是很多"配置了还是报错"的根本原因。

生产环境:推荐用反向代理,而不是 CORS

上线后前后端通常同域,用 Nginx 把 API 路径转发到后端即可,从根上避开跨域:

server {
    listen 443 ssl;
    server_name your-domain.com;

    location / {
        root /var/www/dist;
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

前端请求 /api/xxx,同源,没有跨域,也不用在代码里写死后端地址。

小结

开发环境用 CORS 放开方便调试,生产环境优先用反向代理收敛。把这两件事分清,跨域问题基本不会再困扰你。

本文为 探微编程原创,转载请注明出处

// contact

有需求?先聊聊你的项目

不管是一次技术支持、一个完整项目,还是想补一段工程能力,都可以先沟通。我们会先了解需求并给出判断,再谈方案与报价。

wechat
Trdfyl
qq
2356245930
探微编程 微信二维码

扫码添加微信