聊聊跨域那些事
程序员文章站
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方便易用)开启一个简单的服务器,然后每次根据接口的请求规则在服务器请求接口,再把数据返回到客户端,因为服务器是没有同源策略限制的
上一篇: php 截取指定的字符串解决方案