浏览器跨域原理剖析

前言

众所周知,浏览器的安全是基于同源策略,那么什么是同源策略? 它们是如何工作的?
本篇文章将进行详细的说明。

同源策略

我们都知道,跨域访问的问题,那么浏览器是根据哪些因数来判断是否存在跨域的呢?

是否同源的三个因数:

  1. 协议(例如:http)
  2. 域名(例如:www.pandan.xyz)
  3. 端口(例如:80)

只有当两个请求的这三个因数都相同的时候,浏览器才会认为是同源的,只要其中一个不同则是不同源的。

跨域限制

  1. Cookie、LocalStorage 和 IndexDB 无法读取。
  2. DOM节点元素无法获得。
  3. AJAX 请求不能发送。

如何绕过跨域限制

虽然为了安全这些限制是必要的,但是有时也很不方便,合理的用途也受到影响。下面将详细介绍,如何规避上面三种限制。

  1. Cookie跨域共享

    Cookie 是服务器写入浏览器的一小段信息,只有同源的网页才能共享。但是,两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain来共享Cookie。

    例如:www.pandan.xyz和pom.pandan.xyz两个域名,可以设置cookie的domain=.pandan.xyz,这样在两个域名下都可以读取到这个cookie信息了。

  2. DOM节点元素无法获得

    如果两个网页不同源,就无法拿到对方的DOM。典型的例子是iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。

    比如,父窗口运行下面的命令,如果iframe窗口不是同源,就会报错。

    document.getElementById("myIFrame").contentWindow.document
    // Uncaught DOMException: Blocked a frame from accessing a cross-origin frame

    子窗口获取父窗口的DOM,也会报错。

    window.parent.document.body
    // Uncaught DOMException: Blocked a frame from accessing a cross-origin frame.

    如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。

  3. AJAX 请求不能发送

    同源策略规定,AJAX请求只能发给同源的网址,否则就报错。但是对于资源加载和form表单提交的请求是不受同源策略限制的。我们可以通过这点来间接绕开同源限制。

    3.1. JSONP方式

    JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。

    它的基本思想是,网页通过添加一个