美文网首页
同源策略产生和如何跨域请求

同源策略产生和如何跨域请求

作者: 扶搏森 | 来源:发表于2017-10-12 13:44 被阅读0次

    浏览器同源策略

    含义

    所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。比如源a的js不能读取或设置引入的源b的元素属性。
    那么先定义下什么是同源,所谓同源,就是指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可。

    同源是指

    * 协议相同
    * 域名相同
    * 端口相同
    

    目的

    同源策略的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。浏览器同时访问2个跨域网站,如果A可以访问B网站的信息,那么就数据随时会被别人窃取。

    限制范围

    随着互联网的发展,"同源政策"越来越严格。目前,如果非同源,共有三种行为受到限制。

    * Cookie、LocalStorage和IndexDB无法读取。
    * DOM 无法获取。
    * AJAX 请求不能发送。
    

    跨域的几种解决方法

    Cookie

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

    举例来说,A网页是http://w1.example.com/a.html,B网页是http://w2.example.com/b.html,那么只要设置相同的document.domain,两个网页就可以共享Cookie。

    document.domain = 'example.com';
    

    现在,A网页通过脚本设置一个Cookie。

    document.cookie = "test1=hello";
    

    B网页就可以读到这个 Cookie。

    var allCookie = document.cookie;
    

    注意,这种方法只适用于 Cookie 和 iframe 窗口,LocalStorage 和 IndexDB 无法通过这种方法,规避同源政策,而要使用其他方法规避。

    也可以通过后台服务器端设置Cookie的时候,指定Cookie的所属域名为一级域名,比如.example.com

    Set-Cookie: key=value; domain=.example.com; path=/
    

    iframe

    通过下面2个方法,去获取不同源的iframe里面的DOM或者iframe里面获取外面的DOM,都会跨域

    document.getElementById("myIFrame").contentWindow.document
    window.parent.document.body
    

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

    这3种方法在这里就不过多描叙了,就是通过url的hash值和iframe里面通信

    * 片段识别符(fragment identifier)
    * window.name
    * 跨文档通信API(Cross-document messaging)
    

    JSONP

    它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

    首先,网页动态插入<script>元素,由它向跨源网址发出请求。

    function addScriptTag(src) {
      var script = document.createElement('script');
      script.setAttribute("type","text/javascript");
      script.src = src;
      document.body.appendChild(script);
    }
    
    window.onload = function () {
      addScriptTag('http://example.com/ip?callback=foo');
    }
    
    function foo(data) {
      console.log('Your public IP address is: ' + data.ip);
    };
    

    上面代码通过动态添加<script>元素,向服务器example.com发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSOPNP是必需的。

    服务器收到这个请求以后,会将数据放在回调函数的参数位置返回。

    foo({
      "ip": "8.8.8.8"
    });
    

    由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。

    WebSocket

    WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

    相关文章

      网友评论

          本文标题:同源策略产生和如何跨域请求

          本文链接:https://www.haomeiwen.com/subject/fkonyxtx.html