前端跨域问题解决方案:CORS 配置与代理转发实战

14 ℃ 0 条
内容摘要前端接口报出 blocked by CORS policy 是联调中最常见的拦截问题,根源是浏览器同源策略。本文从同源判定讲起,给出 CORS 响应头配置、预检请求处理以及代理转发三种方案,并说明携带凭证请求与 Nginx 反向代理的关键细节。
前端跨域问题解决方案:CORS 配置与代理转发实战

调后端接口时报出 blocked by CORS policy 是前端联调常见问题,根源是浏览器同源策略:协议、域名、端口任一不同即判定为跨域。本文给出 CORS 响应头、预检与代理转发三种方案。

一、跨域的本质与同源策略

1. 同源的判定标准

同源策略要求协议、域名、端口完全一致。http://a.com 与 https://a.com 协议不同,与 http://a.com:8080 端口不同,都算跨域。任一项不匹配,浏览器就阻止脚本读取响应;请求其实已到服务器,被拦的只是读取响应。

2. 简单请求与预检请求

方法为 GET、POST、HEAD 且 Content-Type 是表单类(text/plain、x-www-form-urlencoded、multipart/form-data)的是简单请求,直接发出;否则(自定义头、json、PUT、DELETE)会先发 OPTIONS 预检,服务端需返回 204 和对应响应头。预检结果默认缓存 5 秒,可用 Access-Control-Max-Age 延长。

二、服务端配置 CORS 响应头

1. 基础响应头

服务端加上 Allow-Origin 即可放行,关键三项是来源、方法、请求头。

// Node.js 设置 CORS 响应头
res.setHeader('Access-Control-Allow-Origin', 'https://www.example.com')
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS')
res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization')
if (req.method === 'OPTIONS') return res.sendStatus(204)

不要把 Allow-Origin 写成通配符;放行多来源时按请求头 Origin 匹配白名单后回填,否则任意站点都能读取接口。

2. 携带凭证的请求

带 Cookie 或 Authorization 时,前端要设置 credentials 为 include,服务端须把 Allow-Credentials 设为 true,且 Allow-Origin 不能用通配符,必须回填具体来源。

三、开发与生产环境的代理转发

1. 开发环境用脚手架代理

前后端端口不同时,让开发服务器代理一层,浏览器看到的就是同源请求。

// vue.config.js
devServer: {
  proxy: { '/api': { target: 'http://127.0.0.1:8080', changeOrigin: true, pathRewrite: { '^/api': '' } } }
}

changeOrigin 把 Host 改成目标地址;pathRewrite 去掉代理前缀。

2. Nginx 反向代理

生产环境常用 Nginx 把前后端收敛到同一域名,彻底规避跨域。

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

proxy_pass 结尾带斜杠会去掉 /api/ 前缀,不带则原样保留,影响接口是否 404。

关键配置提示

  • 跨域是浏览器行为,服务端之间的调用不受同源策略限制,不要与后端权限校验混谈。
  • 预检请求不带 Cookie,处理 OPTIONS 时不要在鉴权中间件返回 401。

发表评论 (已有0条评论)

快来评论,快来抢沙发吧~