理解几种解决跨域问题方法的原理

跨域的定义?

两个url,协议、域名、端口,只要任意一个不同,就属于跨域

跨域有哪些限制?

  1. Cookie无法读取
  2. Dom无法获取
  3. 窗口无法通信
  4. Ajax请求无法发送

有哪些解决跨域的方法?

按解决的问题类型进行分类

解决Cookie无法获取的问题

document.domain

原理及特点:

  1. 子域名下的页面只要将document.domain设置为一级域名,就可以访问保存在一级域名下的Cookie;另外,将Cookie统一保存在一级域名下,也有利于子域名页面访问和使用

解决Dom无法获取的问题

document.domain

原理及特点:

  1. 父窗口、iframe窗口(或window.open打开的窗口)只要将各自的document.domain设置为一级域名,就可以获取到对方的Dom

解决跨域窗口无法通信的问题

window.name

原理及特点:

  1. window.name不存在跨域限制,也就是说窗口之间可以访问这个属性
  2. 如果在一个窗口内设置了window.name,只要窗口不关闭,即使加载了另一个页面,先前window.name设置的值依然存在
  3. window.name容量大,可以保存较长的字符串
  4. 需要监听window.name的变化,因为只有这样页面才知道有新的数据传递过来,但这样做会很耗性能

window.postMessage

原理及特点:

  1. H5新增的Api,用于窗口之间通信(父窗口与iframe窗口,或window.open打开的窗口)

location.hash & onhashchange

原理及特点:

  1. 窗口Url的hash发生改变时,页面不会刷新
  2. 窗口Url的hash发生改变时,onhashchange事件回调被执行,并且参数中会包含新的hash值

解决Ajax无法发送的问题

JSONP

原理及特点:

  1. 加载无论哪一方的JS脚本都不会存在跨域限制
  2. 服务端将数据放入前端已事先声明的回调函数中并返回,形如:callback({name: 'abc'})
  3. 只支持Get请求,不支持Post请求
  4. 兼容不支持CORS的老式浏览器

Websocket

原理及特点:

  1. 不存在跨域限制

CORS

原理及特点:

  1. XMLHttpRequest原生支持跨域请求,并且支持Post请求
  2. 服务端通过响应头Access-Control-Allow-Origin来告知浏览器哪些域名下的页面可以使用服务器返回的资源
  3. 如果想要在跨域请求中携带Cookie,一方面需要服务器同意(Access-Control-Allow-Credentials: true),另一方面也要指定请求携带(xhr.withCredentials = true),否则即使服务器同意,浏览器也不会发送Cookie
  4. 如果跨域请求需要携带Cookie,那么Access-Control-Allow-Origin就不能设置为通配符(*),而必须设置为发起这个请求的那个Origin

未完待续…