美文网首页
前端浏览器同源策略 2019-08-11

前端浏览器同源策略 2019-08-11

作者: 孙新强 | 来源:发表于2019-08-11 11:38 被阅读0次

    原文参考:http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html

    同源"指的是"三个相同"

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

    三种行为受到限制

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

    规避限制

    Cookie

    • 两个网页一级域名相同,只是二级域名不同,浏览器允许通过设置document.domain共享 Cookie
    a: http://w1.example.com/a.html
    b: http://w2.example.com/b.html
    //A网页通过脚本设置一个 Cookie。
    document.domain = 'example.com';
    //B网页就可以读到这个 Cookie。
    var allCookie = document.cookie;
    
    • 服务器也可以在设置Cookie的时候,指定Cookie的所属域名为一级域名,比如.example.com
    Set-Cookie: key=value; domain=.example.com; path=/
    这样的话,二级域名和三级域名不用做任何设置,都可以读取这个Cookie。
    

    iframe

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

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

    完全不同源的网站,目前有三种方法,可以解决跨域窗口的通信问题

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

    前面两种比较low参见原文

    跨文档通信API (window.postMessage)

    发送:

    popup.postMessage('Hello World!', 'http://bbb.com');
    
    • 第一个参数是具体的信息内容,
    • 第二个参数是接收消息的窗口的源(origin),即"协议 + 域名 + 端口"。
      1. 也可以设为*,表示不限制域名,向所有窗口发送
      1. 设置为/,向所有同源窗口发送

    接收:

    window.addEventListener('message', function(e) {
      console.log(e.data);
    },false);
    

    event,提供以下三个属性。

    • event.source:发送消息的窗口
    • event.origin: 消息来源的网址
    • event.data: 消息内容

    AJAX

    同源政策规定,AJAX请求只能发给同源的网址,否则就报错。

    除了架设服务器代理(浏览器请求同源服务器,再由后者请求外部服务),有三种方法规避这个限制。

    • JSONP
    • WebSocket
    • CORS

    JSONP

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

    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);
    };
    

    WebSocket

    该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
    Sec-WebSocket-Protocol: chat, superchat
    Sec-WebSocket-Version: 13
    Origin: http://example.com
    

    上面代码中,有一个字段是Origin,表示该请求的请求源(origin),即发自哪个域名。
    正是因为有了Origin这个字段,所以WebSocket才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。

    相关文章

      网友评论

          本文标题:前端浏览器同源策略 2019-08-11

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