美文网首页
跨域(补充)

跨域(补充)

作者: Ertsul | 来源:发表于2018-06-05 10:17 被阅读17次

    document.domain

    Cookie是服务器写入浏览器的信息,只有同源的页面才能共享。但是,如果两个页面的一级域名一样,二级域名不一样,则允许通过将两个页面的document.domain共享资源。

    域名的级别

    • 顶级域名/一级域名:比如:.com .cn .org,之后的N级域名就是在前面的(N-1)级域名前追加一级。
    • 二级域名:就是在顶级域名/一级域名前面追加一级,比如:ertsul.cn 或者 baidu.com

    document.domain + Cookie

    举例说明,非同源的两个页面A和B,A的地址为[http://a.example.com/a.html,B的地址为:http://b.example.com/b.html。这时,只要设强制置 A 和 B 的 document.domain 相同,就可以实现跨域请求了。

    // A
    document.domain = 'example.com'
    document.cookie = 'Hello, I save a cookie.'
    // B
    document.domain = 'example.com'
    document.cookie = 'Hello, I save a cookie.'
    

    上面的例子,通过将AB两个页面设置相同的document.cookie,然后在A页面设置一个cookie,在B页面就可以获取A页面的cookie。

    document.domain + iframe

    这种方法的实现原理跟document.domain+Cookie是一样的,都是将两个不同的页面设置相同的document.domain,不同的是不需要通过设置cookie获取数据,而是通过父子两个窗口进行通信。

    举个例子,A和B页面非同源,A页面内嵌一个iframe,加载这B页面。A的地址为:http://a.example.com/a.html,B的地址为:http://b.example.com/b.html

    // A
    <iframe id="iframe" src="http://b.example.com/b.html"></iframe>
    <script>
     document.domain = 'example.com';
     var hi = 'hello';
    </script>
    
    // B
    <script>
     document.domain = 'example.com';
     // 获取父窗口中变量
     alert(window.parent.hi);
    </script>
    

    location.hash + iframe

    什么是location.hash?也就是片段标识符(fragment identifier)?指的是在URL的后面添加#号,这个符号后面的值就是location.hash。这样呢,就可以在不同源的两个页面(iframe父子页面)的后面添加hash值,进行监听。

    举例:AB两个页面非同源,A页面内嵌了一个非同源地址的B页面。【 A将数据通过hash传递给B 】

    // A页面
    <iframe src="A的地址"></iframe>
    <input type="text" name="" value="">
    <button type="button">btnbtn</button>
    <script>
     window.onload = function () { 
     document.getElementsByTagName('button')[0].addEventListener('click', function () { 
     let data = document.getElementsByTagName('input')[0].value
     document.getElementsByTagName('iframe')[0].setAttribute('src', 'A的地址#' + data)
     })
     }
    </script>
    
    // B页面
    <script>
     window.onhashchange = function () { 
     console.log(window.location.hash);
     }
    </script>
    

    分析:A通过hash将数据传递给B,B页面通过window.onhashchange进行监听,通过window.location.hash获取数据。

    window.name

    浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。name值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的name值(2MB)。
    实现思路:A和B为非同源的页面。在A中打开一个新窗口B,在B中将信息写入window.name属性,然后,B跳转到与A同源的另一个页面C(AC同源,C页面可以说是代理页面,可以设置为空白页),这样A窗口就可以获取B窗口的window.name属性值了。

    // 在A打开子窗口B,并在B中写入window属性
    window.name = data
    // B跳转到C(AC同源)
    location = '...'
    // A读取B的window.name
    let data = document.getElementById('myFrame').contentWindow.name
    

    postMessage实现跨域

    postMessage是html5提供的API,即:跨文档通信API(Cross-document messaging),是为数不多的可以跨域操作的window属性之一。这个API为window对象新增加了一个window.postMessage方法,允许跨窗口通信,无论这些窗口是否同源。
    这个API可以解决这些问题:

    • 页面和其打开的新窗口的数据传递。
    • 多窗口之间消息传递。
    • 页面与嵌套的iframe消息传递。
    • 上面三个场景的跨域数据传递。

    postMessage(data, origin)

    这个方法会接受两个参数,这两个参数分别是:

    • data:html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
    • origin:协议+主机+端口号,也可以设置为”*”,表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为”/“。

    举一个例子:

    // A页面
    let newPage = window.open('http://b.example.com', 'title')
    newPage.postMessage('hello, I am a page.', 'http://b.example.com')
    // B页面监听
    window.addEventListener('message', function (e) {
     e.data
    }, false)
    // B向A发送消息(子窗口想父窗口发送消息)
    window.opener.postMessage('Nice to see you', 'http://a.example.com');
    

    这样子,也可以实现跨域的访问。当然,子窗口也可以发送消息给父窗口,父子窗口的监听方法一样。

    message事件对象主要有三个属性:

    • event.source:发送消息的窗口。
    • event.origin:发送消息的网址。
    • event.data:发送的数据。

    CORS

    CORS是跨域资源分享(Cross-Origin Resource Sharing)的缩写。跟JSONP相比较,JSONP只能实现GET方法的请求,而CORS则允许任何类型的请求。

    相关文章

      网友评论

          本文标题:跨域(补充)

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