跨域解决方案推荐
跨域问题对于前端来说,是一个老生常谈的问题了,无论是平时工作中,以及面试中基本都会问到。本文将梳理常见的几种跨域的优缺点,以及建议的跨域解决方案。
基础
什么是跨域?跨域有哪些解决方案?等等基础知识,请参考这篇文章,讲的比较细致,这里就不在啰嗦。
https://segmentfault.com/a/1190000011145364
对比
我们在工作中,用的比较多的三种解决方案:
方案 | 优点 | 缺点 | 适用场合 |
---|---|---|---|
JSONP | 1、使用简单; 2、不需要任何配置; | 1、GET 请求; 2、数据不安全,任何人都可以调用接口; 3、存在 XSS 攻击 ; | 1、安全系数要求低; 2、临时使用的接口; 3、应急接口解决方案; |
CORS | 1、相对安全,但是如果后台配置 Access-Control-Allow-Origin = * 就不那么安全了;2、后台或者 Nginx 需要配置,如果需要携带 Cookie,则前端 Ajax 也需要配置参数; | 1、需要配置跨域的相关参数,比较麻烦; 2、如果跨域的 Origin 配置为 * , 不安全 | 1、运行环境可以自主灵活配置; 2、跨域只能代码层面处理理; |
PROXY 代理 | 1、非常安全,同域请求; 2、前后端代码不需要任何配置 | 1、对运行环境要求较高,需要配置代理; 2、开发时也需要配置代理才能连调接口 | 1、运行环境可以自主灵活配置; 2、安全系数要求比较高; |
PROXY 代理,就是通过代理软件或者 Nginx 将地址进行转发,以达到请求接口的地址在同一个域的目的。
JSONP
最主要的缺点就是 不安全
,所以公司里面建议不要使用!
CORS
CORS,在公司里面用的比较多,对于 CORS 的服务端配置,一般有以下两种方式:
- 在后台代码里统一拦截处理 reponseHeader,设置 CORS 协议头;
- 在 Nginx 配置中,统一拦截返回 response,设置 CORS 协议头;
这两种方案,第一种不需要依赖外部环境,纯粹在代码层面就可以解决问题。对于第二种方案,就比较依赖外部环境。那么,一般这两种方案如何选择呢?我个人给如下建议:
推荐
如果代码层面分层合理,建议直接在代码层面设置拦截器,统一拦截处理 CORS。这么做的好处就是,一套代码无论以后部署在哪里都可以,不需要对外部环境提太多要求,自身系统健壮性比较强。另外,在代码层面处理 CORS 还有个好处,就是在开发连调、测试阶段,也依然可以方便进行。不然如果太依赖外部环境的话,开发连调环节,也需要搭建一套环境做为中间转发,比较麻烦。不推荐
当然,也有人在 Nginx 中配置 CORS,这么做的话,对代码的要求就降低了,不需要考虑跨域问题,但就是多了一个中间环节,无论在开发、测试还是线上,都需要这个中间层,这一点不是很方便。所以,如果是用 CORS,不建议使用 Nginx 配置。
实际项目中,使用 CORS 典型的场景:H5 代码部署在 CDN,而后台部署在某后台服务器上。
这种场景下,典型的 CDN 的环境很难自由配置,而又必须依赖后台接口数据,这时候最好的 办法就是后台代码开发时,就支持跨域。
PROXY 代理
PROXY 代理
的方法就是通过代理层做一次中间的转发,使得对于浏览器来说,就不存在跨域的问题。
这种方式最大的好处就是绝对安全,不会由于跨域引来一些安全风险,但是缺点就是中间需要做一层代理转发。
实际项目中,使用 PROXY 代理典型的场景:给客户或者用户使用的后台系统,原因主要在于:
- 对外的一些后台系统,对于安全性和稳定性要求较高;
- 同时,管理后台对于 Cookie 等状态依赖比较强;
- 后台的一些特殊组件,比如上传组件,有时候对于跨域是比较敏感,所以最好是不跨域,一劳永逸;
如果采用这种方式,那在开发和测试阶段,分别怎么做呢?
本地开发连调
本地 + MockServer
前端代码不需任何配置,只需要 MockServer 配置 CORS
支持跨域请求就可以。
本地 + 他人机器 Server
本地需要安装代理软件,如: Charles
假设,上线后真实的访问路径和接口为:
- 前端页面地址: http://abcd.vivo.com.cn
- 后台接口地址: http://abcd.vivo.com.cn/api
假设,本地和他人机器 Server 真实的服务地址为:
- 前端页面服务: http://localhost:8080 (本地的 Node 服务)
- 后台接口地址: http://172.25.122.86:8888 (他人的 Tomcat 后台服务)
这时候需要配置 Charles
路由 Map Remote
规则:
注意:后台接口的路由规则一定要放在前面,即:/api/* 的路由放在页面。
配置好上面的代理后,地址栏直接访问: http://abcd.vivo.com.cn 即可。
生产环境 Nginx 配置
我们在本地是通过代理软件转发,而测试或者生产环境,则直接通过 Nginx 的规则,就可以将上述的路由规则做转发,达到同样的目的。
配置 nginx.conf
文件:
server { listen 80; server_name abcd.vivo.com.cn; location / { proxy_pass http://172.25.122.85:3000 ; } location ~ /api/ { proxy_pass http://172.25.122.86:8080 ; } }
上述配置可以理解为:
- 监听 80 端口,将
http://abcd.vivo.com.cn
的所有请求服务转发到172.25.122.85:3000
; - 将
http://abcd.vivo.com.cn/api/
或者http://abcd.vivo.com.cn/api/list
等请求转发到http://172.25.122.86:8080
总结
本文主要对比了 3 种常见的解决跨域的方案,同时重点介绍了 CORS
和 PROXY 代理
的一些优缺点,以及最适合的场景,归纳总结一下,就是:
- JSONP,能不用就不用,完全不推荐;
- CORS,最适合用于部署在 CDN 上面的项目,比如:H5 项目;
- PROXY 代理,最合适管理后台,比如:对外的给客户或者用的管理系统;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论