欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

聊聊跨域那些事

程序员文章站 2022-05-05 10:25:31
...

浏览器同源策略:
协议相同,域名相同,端口相同
浏览器同源策略会阻止跨域请求,目的是防止CSRF攻击(跨域请求伪造)

解决方案:
1. JSONP(需要后端逻辑配合)
原理是在请求url上加上callback,callback是请求回调方法的名字,
然后创建script标签,src写上请求url,
服务端把数据传给这个方法名并返回,请求完毕后客户端就会执行callback
执行完可以删掉这个script,避免加载多个同样的script

2. 服务端允许跨域(配合ajax)

// 指定允许其他域名访问,*可以换成具体的域名
// 当然用*号,肯定是不好的,最好是只对某一部分域名开放跨域
header('Access-Control-Allow-Origin:*');
// 响应类型  
header('Access-Control-Allow-Methods:POST');
// 响应头设置  
header('Access-Control-Allow-Headers:x-requested-with,content-type');

这里两个小问题
① 异步非简单请求(请求data为对象的POST请求)会先发送一个options请求去验证,看服务端是否允许跨域,所以服务端需要有个接收options请求的路由并作返回
② 跨域请求不提供凭证( cookie ),所以前端请求要将withCredentials设置为true,服务端也需要设置响应头 Access-Control-Allow-Credentials: true

3. iframe(主域不同)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <div class="box">
        <iframe id="if" src="b.com/b.html" frameborder="0"></iframe>
    </div>
<script>
    var fr = document.getElementById('if'),
        state = 0;;
        if(window.VBArray){//兼容ie
            fr.onreadystatechange = function(){
                if(this.readyState == 'complete'){
                    if(state == 1){
                        // 获取数据
                        data = fr.contentWindow.name;
                    }else{
                        state = 1;
                        // 重置iframe窗口的src保证同源
                        fr.src = 'a.com/blank.html';
                    }
                }
            }
        }else{
            fr.addEventListener('onload',function(){
                if(state == 1){
                    // 获取数据
                    data = fr.contentWindow.name;
                }else{
                    state = 1;
                    // 重置iframe窗口的src保证同源
                    fr.src = 'a.com/blank.html';
                }
            },false);
        }
</script>
</body>
</html>

4. 服务器代理转发(可以用于调用网上的数据接口,很方便)

用Node(当然不限于用Ndoe,可以用其他的,不过Node方便易用)开启一个简单的服务器,然后每次根据接口的请求规则在服务器请求接口,再把数据返回到客户端,因为服务器是没有同源策略限制的