持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情
为什么会有跨域? ——因为浏览器的同源策略
浏览器的同源策略
- 同源策略是一种约定,是浏览器最核心也最基本的安全功能
- 同源策略会阻止一个域的js脚本与另一个域的js进行交互
怎样才算同源?
- 同源指的是页面具有相同的协议、域名和端口号
- 当请求的url的协议、域名、端口三者任意一个与当前页面的不同就发生了跨域
如果不是同源,会有什么限制?
- 无法读取非同源页面cookie、localstorage和indexDB
- 无法接触非同源页面的DOM
- 无法向非同源地址发送请求
跨域的解决方法
- 纯前端方案:跨文档通信API:window.postMessage()
- 页面与其打开的新窗口的数据传递
- 多页面之间的消息传递
- 页面与嵌套iframe的消息传递
- CORS(跨域资源共享)
- 是W3C标准,跨域请求的根本解决方法
- 基于HTTP头的机制,允许服务器标示除了自己以外的其他域加载自己的资源
- 通过浏览器发一个到服务器托管的跨域资源的“预检”请求,也就是OPTION请求,浏览器发送的头中标示有HTTP方法和真实请求中用到的头部
- 一般的跨域请求,只需要服务器设置Access-Control-Allow-Origin
- 带cookie的跨域请求,前后端都要设置
- 前端:withCredentials=true
- 后端:
- Access-Control-Allow-Origin
- Access-Control-Allow-Credentials
- set-Cookie
- websocket
- 双向通信协议,在连接时需要借助HTTP协议,连接建立好之后,双向通信就与HTTP无关了
- NGINX反向代理
- 转发请求,把web项目和后端接口放到一个域中,就不会有跨域问题
- 支持所有浏览器,支持Session,不需要修改任何代码,不会影响服务器性能
- webpack本地代理
- 本地调试时使用,webpack devServer
总结
在前后端分离之后,跨域这个问题就不可避免的出现了,于是出现了多种解决跨域的方法,比如早期的设置document.domain,这个解决方法适合主域相同,子域不同的场景,再到后面的JSONP,支持的请求方法有限,只支持get方法,不支持post方法。再到标准中提到的CORS以及其他的可以解决跨域问题的方法。现在的项目中,跨域这个问题的解决接近于黑盒状态,随着框架和生态越来越完善,通过引入相关的包就能解决这类问题,但是对于前端,还是很有必要清楚请求从发出到返回的路径。