跨域总结

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域总结相关的知识,希望对你有一定的参考价值。

跨域定义

协议、端口号、域名有一个不同就是跨域。
主域名相同,子域名不同也是跨域,emial.aa.com和time.aa.com就是主域名相同,子域名不同的跨域
协议不同或者端口号不同造成的跨域,前端无法解决

跨域解决方法

1. jsonp(Get请求的跨域,安全性低)

1. 生成唯一函数名callback_uuid,在window对象上注册这个函数,window[callback_uuid] = function(){}
2. 将函数名callback_uuid发送到后端,后端生成数据JSON,拼装js文档callback_uuid(JSON),返回给客户端
3. 客户端将script标签插入到文档中,浏览器解析script标签,自动执行callback_uuid方法
4. 真正的callback函数是在callback_uuid中调用,而不是直接调用
代码实现如下:

var jsonp = (function () {
    var num = 0;
    function foo(options) {
        let { url, params, callback } = options;
        num++;
        //通过闭包内的自增数字生成唯一的函数名
        var jsonCallback = ‘jsoncallback_‘ + num;
        //注册函数到全局对象上
        window[jsonCallback] = function (data) {
            //清理回调函数名
            window[jsonCallback] = null;
            //清理script标签
            removeElement(jsonCallback);
            //调用真正的回调函数
            callback && callback(data);
        }
        //插入script标签
        var queryString = Object.keys(params).reduce((pre, cur) => {
                return pre + ‘&‘ + cur + ‘=‘ + option.params[cur];
        }, ‘‘);
        url += ‘callback=‘ + jsonCallback + queryStirng;
        var script = document.createElement(‘script‘);
        script.src = url;
        script.id = jsonCallback;
        document.getElementByTagName(‘head‘)[0].appendChild(script);
    }
    function removeElement(id) {
        var ele = document.getElementById(id),
            parent = ele.parentNode;
        if (parent && parent.nodeType != 11) {
            parent.removeChild(ele);
        }
    }
    return foo;
}());

2. CORS(各种请求均可,IE8,9只能是GET和POST请求,通用性好)
3. iframe(传统POST的最佳选择)

将<form>表单通过一个iframe来submit,将form的target属性设置为iframe的name,这样form的action URL就会在
iframe中打开,服务器返回的数据就会输出到iframe中。通过主页面和iframe的交互,完成对数据的读取。
举例:

<form action="http://www.b.com/io.php" method="POST" enctype="multipart/form-data" target="upload">
    <input type="file" name="upload_file" />
    <input type="hidden" name="backurl" value="http://www.a.com/receive" /> //注意这里!
    <input type="submit" value="开始上传" />
</form>
<iframe name="upload" id="upload" style="display:none"></iframe> //name和id都设置为upload

提交到后端之后,直接通过302跳转的backurl,将返回结果加到backurl的查询字符串里面。backurl必须是和提交的页面
是同域的页面。这样iframe里面的页面可以通过window.top.callback(查询字符串参数)来调用父页面的方法,或者读取iframe
的src中的查询字符串

4. postmessage

postmessage和iframe配合可以实现向后端跨域post数据,并且将返回值传递给主页面。

5. 后端代理或nginx代理

 












以上是关于跨域总结的主要内容,如果未能解决你的问题,请参考以下文章

Nginx 跨域

python常用代码片段总结

BootStrap有用代码片段(持续总结)

跨域问题研究总结

BootStrap实用代码片段(持续总结)

回归 | js实用代码片段的封装与总结(持续更新中...)