前端问题清单——跨域

448 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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以及其他的可以解决跨域问题的方法。现在的项目中,跨域这个问题的解决接近于黑盒状态,随着框架和生态越来越完善,通过引入相关的包就能解决这类问题,但是对于前端,还是很有必要清楚请求从发出到返回的路径。