跨域问题扫盲

toc

常见问题

简单介绍的跨域的核心概念、流程, 并不严谨, 详细准确的内容参考文末的参考资料.

对跨域不了解, 开发过程可能会有这样一些问题:

  • 改了vue/react的代码, 为什么还是报跨域错误?
  • postman不报错, 为什么前端调接口报跨域错误?
  • 为什么有很多options请求?
  • 跨域里的preflight是什么?

为什么会产生跨域

为了安全性考虑, 浏览器制定了"同源策略(same-origin policy)", 导致只能同域名请求, 不能跨域请求;
为了解决跨域请求, 浏览器制定了"跨源资源共享(CORS)", 符合这个规则就能跨域名请求, 不符合这个规则, 浏览器就会报跨域错误;

注意: 两条规则都只跟浏览器有关, 所以postman、java、curl等都不存在跨域问题;

浏览器的同源策略 - Web 安全 | MDN
跨源资源共享(CORS) - HTTP | MDN

跨域请求的流程

  1. 用户使用浏览器打开前端页面: GET http://front.com
  2. 服务端响应: 返回html、js、css等
  3. 浏览器执行js
  4. js发出了一个请求: GET http://gateway.com/self
  5. 浏览器检测到请求是一个跨域请求, 首先发送一个预检(preflight)请求, 询问服务器该接口是否支持跨域: OPTIONS http://gateway.com/self
  6. 服务器接收preflight请求, 如果允许跨域, 则在响应头中添加Access-Control-Allow-Origin、Access-Control-Allow-Methods等header
  7. 浏览器收到preflight的响应, 如果确认可以跨域请求, 则发出真正的请求: GET http://gateway.com/self
  8. 服务端接收请求, 返回数据, 响应头添加Access-Control-Allow-Origin等header
  9. 浏览器接收到响应, 如果符合CORS规则, 则把返回结果传递给js;

其中5-9步出现问题就会导致跨域错误, 比如: preflight的options请求返回401、返回的响应头里没有Access-Control-Allow-Origin等header、Access-Control-Allow-Origin不匹配等等

如何解决跨域报错

修改后端服务器

根据跨域请求的流程, 只要后端开启跨域支持、允许跨域就行了;

spring-boot里可以用CorsRegistry@CrossOrigin、filter等方式解决;

加一层代理

后端代码是第三方开发的, 不能修改源码增加跨域配置, 怎么办?

可以在中间加一层代理, 前端先请求代理、代理再请求真实地址; 常见的方式:

  • 配置和前端同域的代理: 如开发时使用webpack-dev-server
  • 配置开启了跨域的代理: 如nginx反向代理、gateway代理;

参考资料

博客:
不要再问我跨域的问题了 - SegmentFault 思否
15 张精美动图全面讲解 CORS - SegmentFault 思否

官方资料:
浏览器的同源策略 - Web 安全 | MDN
跨源资源共享(CORS) - HTTP | MDN

CORS support in Spring Framework

posted @ 2021-04-21 21:37  QIAOXINGXING001  阅读(93)  评论(0编辑  收藏  举报