跨域及常见解决方案
本文主要讲解什么是跨域以及跨域的解决方案
一、什么是跨域
- 同源策略
为了安全起见,浏览器必须保证只有 协议+域名+端口 一模一样才允许发 AJAX 请求。
二、跨域的解决方案
跨域的解决方案很多,最常见的解决方案有:CORS
、JSONP
、代理转发
、WebSocket
。
1、CORS
CORS
是当前适用场景最广泛,也是最新、最受推崇的一种跨域解决方案。主要操作就是在服务端的响应头中设置 Access-Control-Allow-Origin
。
2、JSONP
JSOP
是一种传统的跨域解决方案,有一定局限性(仅支持 GET 请求),目前很少使用。
- 首先,有些 html 标签(form、a、img、link、script)可以实现 get 请求,例如:
1 | button.addEventListener('click', e => { |
JSONP 基本原理:
- 请求方创建 script,src 指向响应方,同时传一个查询参数 ?callbackName=yyy
- 响应方根据查询参数 callbackName,构造形如这样的响应
- “yyy.call(undefined, data)”
- “yyy(data)”
- 浏览器接收到响应,就会执行 yyy.call(undefined, data)
- 那么请求方就知道了他要的数据
下面是实现代码:
1 | button.addEventListener('click', e => { |
3、使用 Nginx(或其它服务器)转发
- 使用 Nginx(或其它服务器)将请求代理转发可以很方便解决跨域问题。它的原理也是基于
CORS
的。首先,我们应该明白,出现跨域问题是浏览器的安全机制引起的,浏览器拒绝请求非同源 URL。对于服务端程序是没有这个限制的。所以我们可以通过一个轻便的服务器(常用 Nginx)对非同源请求进行转发,转发的同时设置响应头Access-Control-Allow-Origin
的值为*
或者目标地址,这样浏览器直接请求 Nginx 代理转发后的 URL 地址就不会出现跨域报错。 - 使用这种方式解决跨域问题的一个优势就是不需要更改服务端代码,缺点就是增加了网络请求的复杂度和流程,会影响性能,也增加了系统部署复杂度。
- 下面给出 Nginx 反向代理的一个简单配置。
1 | server { |
上面配置中,$http_origin
是 nginx 中的一个默认变量,其值为请求方的地址。上述配置中,实际的服务地址为 http://127.0.0.1:8888
,转发后的地址为 http://127.0.0.1:8091
,前端直接请求 http://127.0.0.1:8091
即可。下面为请求结果:
4、WebSocket
5、Chrome 插件:Allow-Control-Allow-Origin: *
该插件可谓是前端开发利器,可帮助我们在开发中临时解决跨域问题。
该插件实现跨域的机制是:利用 CHrome 浏览器开发接口,拦截了每次的 HTTP 请求,并修改了请求头和响应头信息,主要是添加了 Access-Control-Allow-Origin: *
。基本原理是
- 欺骗浏览器:在 Option 预请求中,将响应头中的
Access-Control-Allow-Origin
篡改为你发请求的客户端地址,这样就可以通过浏览器的校验; - 欺骗服务器:在真实请求中,将请求头中的
Origin
修改为服务器允许的地址,这样就可以通过服务端的校验;
关于该插件的详细机制和原理可以查看这里。类似改功能的插件还有几个,可以自己在谷歌应用点查找。
参考
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章