外观
开发环境的代理为什么能绕过跨域?
浏览器只和开发服务器通信,这个请求是同源的。开发服务器再替浏览器去请求真正的接口。跨域限制作用在浏览器里的脚本上,服务器之间的请求不受这套限制。
原理
配置把 /api 转到 http://localhost:3000,并可以去掉或改写路径。浏览器看到的地址仍是开发服务器的源,所以没有 CORS 预检。响应回到浏览器时,也是开发服务器给的。
Cookie 和 Host 要单独看。目标服务器如果校验 Host 或 Origin,需要在代理里改头。登录态 Cookie 的域是接口域时,浏览器不会把它存成开发服务器的 Cookie,除非代理改写 Set-Cookie 的 Domain 和 Path。
这只存在于开发服务器。生产环境没有这个代理,就要么接口配置 CORS,要么由自己的后端转发。见 跨域。
改目标地址、WebSocket 代理要单独打开支持。代理缓存了错误的目标时,重启开发服务器。
追问
为什么线上又跨域了?
线上页面和接口是两个源,没有开发服务器挡在中间。上线前用生产的域名走一遍登录和预检,不要只在代理环境里测。
代理能代替 CSRF 防护吗?
不能。它只是开发时的转发。生产请求该带的令牌和 Cookie 策略不变。
易错点
- 把代理写进生产构建配置,以为用户浏览器也会走 Webpack。
- 路径重写多删或少删一段,接口 404,误当成跨域。
- 忘记转发
Authorization。自定义头默认会过去,但被自己的headers配置覆盖时会丢。