同源策略

javascript 语言在设计之初为了安全考虑,不允许调用其它页面的对象。 跨域是由 javascript 语言安全限制中的同源策略造成的。 同源策略指的是,一段脚本只能读取来自同一来源的窗口和文档的属性,(同一来源指的是域名协议端口号的组合) 简单来讲,即不允许同一域名下的不同端口号,不同协议(http,https),不用子域名(www.dxy.cn 和 app.dxy.cn)及域名和域名对应的 ip 也不允许。

解决跨域的原理

HTML 中,静态资源是没有跨域限制的。在 HTML DOM 中,script 标签是可以跨域访问服务器上的数据的。所以我们可以手动插入 script 标签等方法来伪造。 不过,有个限制是,服务器返回 内容不能单纯为一个 json 字符串,可定变量或函数实现,如: var json = {"type":"json"}json({"type":"json"})。jsonp 即采用后者形式。

解决方案

  1. 手动插入script标签的形式。
  2. jsonp … 它能对老的浏览器也保持支持。 但是,只支持 get 不支持 post 等其它类型的 HTTP 请求。
  3. 跨域资源共享(CORS) 使用自定义的 HTTP 头部让浏览器与服务器进行沟通,从而决定请求的成功或者失败。 服务器端对于 CORS 的支持,主要通过 Access-Control-Allow-Origin 进行

    var xhr = new XMLHttpRequest();
    xhr.open('get', '/xx', true);
    xhr.send();
    
  4. iframe + domain 对于主域相同而子域不同,则可以只用 document.domain 来实现跨域。

    e.g. 在 http://a.com/test.htmlhttp://sub.a.com/test2.html 中分别加上 document.domain = a.com,然后 test.html 页面中创建 iframe 来控制iframe的内容文档。

    注意的是:

    • domain 指向的是主域。 (如 a.com , www.a.com 其实是二级域名)
    • document.domain 需设置为自身或更高一级的父域
    • 浏览器限制2 为,不同域的框架之间是不能进行 js 的交互的(可取到 window对象,但取不到 window 对象的属性和方法,PS: html5中的 postMessage 例外)。
  5. window.name window.name 值在不同页面(包括不同域下)加载后依旧存在(当然关闭窗口后就销毁了)。注意的是,window.name 由大小限制,一般为2M。

  6. HTML5 window.postMessage

  7. 隐藏 form, target 指向一个隐藏的 iframe