前端处理跨域问题
前端开发基本都会遇到跨域问题,我做项目的时候也不例外,为此我稍微整理了几个简单好用的跨域解决方案
跨域错误信息产生的原因
- 浏览器端的限制(即浏览器的同源策略限制,此时服务端收到了请求并正确返回)
- 发送的是 XMLHttpRequest 请求
- 请求了不同域的资源
只有同时满足了这三个条件,浏览器才会产生跨域错误
同源策略限制内容有:
Cookie、LocalStorage、IndexedDB 等存储性内容
DOM 节点
AJAX 请求不能发送
但是img link script三个标签是允许跨域加载资源的
跨域错误处理方案
- JSONP
-
跨域资源共享CORS
-
webpack配置proxy反向代理
1.JSONP
1)JSONP原理
利用script元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON 数据。JSONP请求一定需要对方的服务器做支持才可以。JSONP和AJAX相同,都是客户端向服务器端发送请求,从服务器端获取数据的方式。但AJAX属于同源策略,JSONP属于非同源策略(跨域请求)
2)JSONP的流程
声明一个回调函数,其函数名(如fn)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。
然后创建一个请求,服务器接收到请求后,需要进行特殊的处理:把传递进来的函数名和它需要给你的数据拼接成一个字符串,例如:传递进去的函数名是fn,它准备好的数据是fn([{“name”:“jianshu”}])。
最后服务器把准备的数据通过HTTP协议返回给客户端,客户端再调用执行之前声明的回调函数(fn),对返回的数据进行操作。
<script type="text/javascript">
function fn(data){
alert(data.msg);
}
</script>
<script type "text/javascript" src "http://crossdomain.com/jsonServerResponse? jsonp=fn"></script>
其中 fn 是客户端注册的回调的函数,目的获取跨域服务器上的json数据后,对数据进行在处理。
最后服务器返回给客户端数据的格式为:
fn({ msg:'this is json data'})
2.CORS
1)CORS原理
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
2)CORS优缺点
CORS要求浏览器(>IE10)和服务器的同时支持,是跨域的根本解决方法,由浏览器自动完成。
优点在于功能更加强大支持各种HTTP Method,缺点是兼容性不如JSONP。
3)CORS流程
CORS只需要在服务器端做一些小小的改造即可 (在头信息之中,增加'Access-Control-Allow-Origin',若要带cookie请求:前后端都需要设):
例如:网站http://localhost:{{63342:0}}/ 页面要请求http://localhost:3000/users/userlist 页面,userlist页面返回json字符串格{name: ‘Mr.Cao’, gender: ‘male’, career: ‘IT Education’}
//在服务器端设置同源策略地址
router.get("/userlist", function (req,res, next){
var user - {name:'Mr.cao' , gender: 'male', career: 'IT Education'};
res.writeHeader (200,{ "Access-Control-Allow-Origin": ' http://localhost:{[63342:0]}'});
res.write(JSON.stringify(user));
res.end();
});
3.反向代理
1)原理
在浏览器中创建了代理服务器,缺点渲染效率降低
2)实现
在webpack.config.js文件里配置:
const url = 'http://192.168.0.111:9999' //服务器端接口地址
module.exports = {
//...
devServer: {
proxy: {
'/api': { //这里最好有一个 /
target: url, // 服务器端接口地址
ws: true, //如果要代理 websockets,配置这个参数
secure: false, // 如果是https接口,需要配置这个参数
changeOrigin: true, //是否跨域
pathRewrite:{'^/api':''}
}
}
}
};
此时访问的接口地址在本地被解析为localhost:8080/api/***
访问的真实地址是http://192.168.0.111:9999***
除了这三个处理跨域的方案之外,还有WebSocket、postMessage方案,感兴趣的可以到https://blog.csdn.net/qq_43239820/article/details/89186319了解。
本文来自博客园,作者:不如饲猪,转载请注明原文链接:https://www.cnblogs.com/ifeelthecall/p/15056773.html

浙公网安备 33010602011771号