一、简介

跨域(CORS, Cross-Origin Resource Sharing)是浏览器出于安全策略(同源策略)限制,阻止一个源(origin)的网页向另一个源发起某些请求的行为。

🔒 什么是“同源”?
协议(scheme)+ 域名(host)+ 端口(port)三者完全一致才算同源。

例如:

https://api.example.com:443 和 https://www.example.com:443 → 不同源(域名不同)
http://localhost:3000 和 http://localhost:8080 → 不同源(端口不同)
🌐 跨域请求的两种类型

  • 简单请求(Simple Request)
    • 满足以下条件:
      方法:GET、POST、HEAD
      头部仅限:Accept、Accept-Language、Content-Language、Content-Type(且值只能是 application/x-www-form-urlencoded、multipart/form-data、text/plain)
      无自定义头部(如 Authorization、X-Token 等)
      ✅ 浏览器直接发送请求,但会检查响应头是否允许跨域。
  • 预检请求(Preflight Request)
    • 不满足上述条件时,浏览器先发一个 OPTIONS 请求询问服务器:“你允许这个跨域请求吗?”
      只有预检通过,才发送真正的请求。

二、后端如何解决跨域

核心:在响应中添加 CORS 相关 HTTP 头部

  1. 基础 CORS 响应头(Nginx / 应用层均可配置)
Access-Control-Allow-Origin: https://your-frontend.com
# 或 *(但不能用于带凭证的请求)
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With
Access-Control-Allow-Credentials: true  # 如果需要携带 Cookie

⚠️ 安全建议:生产环境不要用 *,应明确指定可信源。

  1. 在 Nginx 中统一处理(推荐)
location /api/ {
    # 允许的源(可设为变量或具体域名)
    add_header 'Access-Control-Allow-Origin' 'https://your-frontend.com' always;
    add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
    add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type,Authorization' always;
    add_header 'Access-Control-Allow-Credentials' 'true' always;

    # 处理预检请求
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Max-Age' 86400;  # 预检结果缓存 24 小时
        add_header 'Content-Length' 0;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        return 204;
    }

    # 代理到后端服务
    proxy_pass http://backend;
}

✅ 使用 always 参数确保 4xx/5xx 错误响应也包含 CORS 头。

如果不设置always参数,以Access-Control-Allow-Origin为例。 Access-Control-Allow-Origin只在 2xx / 3xx 响应里出现;一旦后端返回 4xx / 5xx,这个头会被直接丢弃,浏览器仍然会报跨域被拦。
因此,如果接口可能返回 4xx / 5xx 且仍需跨域调试,就必须加上 always,否则 4xx / 5xx 响应会因为缺少该头而再次触发浏览器的 CORS 阻断。

  1. 在应用代码中处理
    如:Django (Python)中,安装 django-cors-headers,配置:
CORS_ALLOWED_ORIGINS = ["https://your-frontend.com"]
CORS_ALLOW_CREDENTIALS = True
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐