跨域

作者: 啃香菜的花萝萝 | 来源:发表于2019-07-07 12:00 被阅读0次

1. 同源策略

浏览器提出同源策略的机制。
同源:协议,域名,端口相同
http默认端口号:80
https默认端口号: 443


2. 解决跨域问题的几种方法

  • Flash
  • 服务器代理中转
  • document.domain
  • Jsonp

3. Jsonp

注意:Jsonp请求都是 get 请求

  • 原理
  1. web页面上用 script 引入js文件时不受是否跨域的影响。(iframe, img, script 凡是拥有 ‘src’ 这个属性的标签都拥有跨域能力)
  2. 把数据放到服务器上,数据格式为json
  3. 因为无法监控通过 <script> 的 src属性是否把数据获取完成,所以需要做一个处理。
  4. 实现定义好处理跨域获取数据的函数,如:function aa(data) {}
  5. 用 src 获取数据的时候添加一个 cb='aa' (服务端会根据参数cb的值返回对应的内容)

下面举个例子:

<body>  
    <script>
        var oScript = document.createElement('script');
        oScript.src = './jsonp.txt?cb=aa';
        document.body.appendChild(oScript);

        var oScript = document.createElement('script');
        oScript.src = './jsonp.txt?cb=bb';
        document.body.appendChild(oScript);

        function aa(data) {
            console.log(data);
        }
        function bb(data) {
            console.log(data);
        }
    </script>
</body>
// jsonp.txt
aa({"name":"sun"});
bb({"age":"18"});
效果

4. cors (cross-origin-resource-sharing)

后端在响应头中添加一个响应头Access-Control-Allow-Origin: *, 星号表示所有域全部都能访问。


5. 父页面与子页面之间的通讯

5.1 iframe
  • iframe 就是一个标签
  • 可以在一个网页中嵌入另一个网页; 通常用于做 广告植入,在线编辑器等。
  • 解决ajax化网站响应浏览器前进后退按钮的方案。

5.2 父子窗口之间数据传递
  • 获取子窗口 (限制:父子窗口必须同源)
  1. document.getElementsByTagName('iframe')[0].contentWindow
  2. document.getElementsById('id').contentWindow
  3. 简易写法:window.frames['iframe的name'] 注意: 部分浏览器不支持!!!
  4. IE专用document.iframes[name].contentWindow
  5. IE专用document.iframes[i].contentWindow
  • 父子页面窗口的关系
  1. window.self:就是自己
  2. window.parent: 父级窗口对象
  3. window.top: 顶级窗口对象
  • 判断 iframe 加载完成
  1. 非 ie 下使用 onload 事件: iframe(dom).onload = function() {}
  2. ie下使用 onreadystatechange 或者设定计时器
iframe.onreadystatechange = function () {
  if (iframe.readyState == 'complete' || iframe.readyState == 'loaded') {
    alert ('Local iframe is now loaded.');
  }
}

举个例子:
父获取子页面中的数据; 子获取父页面中的数据

// child html
...
<body>
    Child
    <script>
        var name = 'sun';
        var age = 18;
        // 子获取父页面中的数据
        console.log(window.parent.fatherValue);
    </script>
</body>
...
// father html
...
<body>
    <iframe src="./childWindow.html" frameborder="1"></iframe>

    <script>
        var fatherAge = 30;
        var oIframe = document.getElementsByTagName('iframe')[0];
        oIframe.onload = function () {
            console.log(oIframe.contentWindow.age);
        }
    </script>
</body>
...
image.png
5.3 iframe 实现跨域

1. 使用哈希值 (只能父传给子)
这个方法需要使用定时器频繁的检测数据是否发生改变。不是神马好方法嗷。

// 父页面
<body>
    <iframe src="http://127.0.0.1:5500/ajax/childWindow.html" frameborder="1" name="childW"></iframe>

    <script>
        var fatherValue = 30;
        var oIframe = document.getElementsByTagName('iframe')[0];
        var oSrc = oIframe.src;

        document.onclick = function() {
            oIframe.src = oSrc + '#' + fatherValue;
            fatherValue ++;
        }
    </script>
</body>
<body>
    Child

    <script>
        var age = 18;
        var lastHash = window.location.hash;

        setInterval( function () {
            if (lastHash !== window.location.hash) {
                console.log(location.hash.slice(1));
                lastHash = window.location.hash;
            }      
        }, 10);
    </script>
</body>
效果

2. window.name
在一个窗口的生命周期中(被关闭前),窗口载入的所有页面同时共享一个 window.name,每个页面对window.name都有读写的权限。

3. PostMessage
待续 ...

相关文章

网友评论

      本文标题:跨域

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