Skip to content

跨域的解决方式 #39

Open
Open
@hungeraibin

Description

@hungeraibin
Owner

1.JSONP

1.1 JSON简介

JSONP是一种数据调用方式,是解决JSON跨域获取的解决方案。

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

1.2 JSONP的具体实现流程代码讲解

  1. 定义数据处理函数appendHtml。
    function appendHtml(news){
        var html = '';
        for( var i=0; i<news.length; i++){
            html += '<li>' + news[i] + '</li>';
        }
        console.log(html);
        $('.news').innerHTML = html;
    }
  1. 创建script标签,src的地址执行后端接口,最后加个参数callback=appendHtml。
    $('.change').addEventListener('click', function(){
        var script = document.createElement('script');
        script.src = 'http://localhost:8080/getNews?callback=appendHtml';
        document.head.appendChild(script);
        document.head.removeChild(script);
    });
  1. 服务端在收到请求后,解析参数,计算返还数据,输出 appendHtml(data) 字符串。
    var cb = req.query.callback;
    if(cb){
        res.send(cb + '('+ JSON.stringify(data) + ')');
    }else{
        res.send(data);
    }
  1. appendHtml(data)会放到script标签做为js执行。此时会调用appendHtml函数,将data做为参数。
    image

2.CORS

2.1 CORS简介

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

2.2 CORS的具体实现流程代码讲解

  1. 当你使用 XMLHttpRequest 发送请求时,浏览器发现该请求不符合同源策略,会给该请求加一个请求头:Origin,后台进行一系列处理。
  2. 如果确定接受请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin;
  3. 浏览器判断该相应头中是否包含 Origin 的值
  • 如果不包含浏览器直接驳回,这时我们无法拿到响应数据。
    $('.change').addEventListener('click', function () {
        var xhr = new XMLHttpRequest();
        xhr.open('get', 'http://b.jrg.com:8080/getNews', true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                appendHtml(JSON.parse(xhr.responseText))
            }
        };
        window.xhr = xhr
    });

结果会发生报错:没有响应头被允许

image

  • 如果有则浏览器会处理响应,我们就可以拿到响应数据,
    res.header("Access-Control-Allow-Origin", "http://a.jrg.com:8080");
    //res.header("Access-Control-Allow-Origin", "*");

可实现CORS跨域:响应头被允许

image

3.降域

3.1 为什么要降域

如果在域名a.jrg.com通过js操作b.jrg.com将会报错:浏览器阻止访问不同源的iframe

    <iframe src="http://b.jrg.com:8080/b.html" frameborder="0" ></iframe>

image

3.2 降域的具体实现流程代码讲解

原理:通过修改document.domain来跨域操纵页面上的iframe

    document.domain = "jrg.com"

image

4.postMessage

4.1 postMessage原理

降域实现跨域调用iframe数据,有着同父级域名的限制,为了摆脱同父级域名的限制,可以使用postMessage

4.2 postMessage的具体实现流程代码讲解

  1. 主页面a.html向ifame页面b.html加入postMessage信息
    $('.main input').addEventListener('input', function(){
        console.log(this.value);
        window.frames[0].postMessage(this.value, '*');
    });
        $('.main input').value = e.data;
        console.log(e.data);
    });
  1. iframe页面b.html向父页面a.htm加入postmessage信息
    $('#input').addEventListener('input', function(){
        window.parent.postMessage(this.value, '*');
    });
    window.addEventListener('message',function(e) {
        $('#input').value = e.data;
        console.log(e.data);
    });

实现跨域:不同父级域名

image

Activity

dajiyuanzi

dajiyuanzi commented on Jul 28, 2019

@dajiyuanzi

兄台在哪里高就啊?我今年6月也是参加了jirengu的网课

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @dajiyuanzi@hungeraibin

        Issue actions

          跨域的解决方式 · Issue #39 · hungeraibin/blog