美文网首页
跨域解析(更新中)

跨域解析(更新中)

作者: Zulu_c02a | 来源:发表于2020-09-12 21:30 被阅读0次

    一 、原理

    跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。而我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。

    二、 跨域解决方案

    1、 通过jsonp跨域
    2、 document.domain + iframe跨域
    3、 location.hash + iframe
    4、 window.name + iframe跨域
    5、 postMessage跨域
    6、 跨域资源共享(CORS)
    7、 nginx代理跨域
    8、 nodejs中间件代理跨域
    9、 WebSocket协议跨域

    1.JSONP跨域

    基于script标签可以从加载其他域下的js的特性,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。再通过请求的脚本有一个callback参数,用来告诉服务器,客户端的回调函数名称,同时在js中声明函数。

    <script>
    var script = document.createElement('script');
    script.type = 'text/javascript';
    // 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback';
    document.head.appendChild(script);
    // 回调执行函数
    function handleCallback(res) {
    alert(JSON.stringify(res));
    }
    </script>

    服务端返回如下(返回时即执行全局函数):

    handleCallback({"status": true, "user": "admin"})

    jsonp缺点:只能实现get一种请求。

    2.document.domain + iframe跨域

    此方案仅限主域相同,子域不同的跨域应用场景。
    实现原理:两个页面都通过js强制设置document.domain为基础主域,就实现了同域。

    3. postMessage跨域

    postMessage是HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以 跨域操作 的window属性之一,它可用于解决以下方面的问题:
    a.) 页面和其打开的新窗口的数据传递
    b.) 多窗口之间消息传递
    c.) 页面与嵌套的iframe消息传递
    d.) 上面三个场景的跨域数据传递

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

    a.html:(http://www.domain1.com/a.html))

    <iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;">

    </iframe>
    <script>
    var iframe = document.getElementById('iframe');
    iframe.onload = function() {
    var data = {
    name: 'aym'
    };
    // 向domain2传送跨域数据
    iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com');
    };
    // 接受domain2返回数据
    window.addEventListener('message', function(e) {
    alert('data from domain2 ---> ' + e.data);
    }, false);
    </script>

    b.html:(http://www.domain2.com/b.html))

    <script>
    // 接收domain1的数据
    window.addEventListener('message', function(e) {
    alert('data from domain1 ---> ' + e.data);
    var data = JSON.parse(e.data);
    if (data) {
    data.number = 16;
    // 处理后再发回domain1
    window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com');
    }
    }, false);
    </script>

    5. 跨域资源共享(CORS)

    ①服务端设置

    CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨域的服务器,发出XMLHttpRequest请求,从而克服了 AJAX 只能同源使用的限制。整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。
    对于开发者来说,CORS 通信与普通的 AJAX 通信没有差别,代码完全一样。浏览器一旦发现 AJAX 请求跨域,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感知。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。

    ②后端设置

    参考:
    https://segmentfault.com/a/1190000011145364
    https://wangdoc.com/javascript/bom/same-origin.html#navbar

    相关文章

      网友评论

          本文标题:跨域解析(更新中)

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