只要经常开发前端的程序员对跨域肯定不陌生,尤其是在如今前后台分离开发的模式,前台和后台并不在一个服务器上,所以跨域成了不可避免的问题。
以前因为项目开发模式还是老旧的jsp,服务都在一台服务器上,所以一直没过多了解。这次开发新项目时想去尝试学习Vue,采用了前后端完全分离的开发模式,在本地测试的时候因为端口号导致ajax请求失败。既然遇到了,这次就一定要把跨域彻底搞清楚,并找到解决方案。
在解决之前,先来了解一下跨域是什么,官方说法:跨域;
看过之后应该对跨域和解决方案CORS是什么有个简单了解了吧。
跨域问实际上是为了保证网站内容的安全,对于非同源的访问做了限制。具体的细节我就不多说了,直接上解决方案:
1.简单请求:
请求方法限制:HEAD,GET,POST
请求头限制:
不允许有自定义请求头选项,只能包含以下几个请求头:
* Accept
* Accept-Language
* Content-Language
* Content-Type
* DPR
* Downlink
* Save-Data
* Viewport-Width
* Width
其中Content-Type只能是:application/x-www-form-urlencoded、multipart/form-data、text/plain;
2.服务器端允许跨域
简单请求是协议天然允许的,只是有一些限制,但是这些简单请求显然无法满足我们的需求,尤其是Ajax的跨域,此时就需要让服务器允许跨域请求的访问。
原理就不细说了,CORS的文档中有详细介绍,简单点就是:
一个跨域请求的在发送之前,浏览器会先向服务器发送一条请求(官方叫做:Preflighted requests),其中头信息包含:
- Origin: http://foo.example
- Access-Control-Request-Method: POST
- Access-Control-Request-Headers: X-PINGOTHER, Content-Type
用来告知服务器跨域请求的信息,然后服务器给予回应告诉浏览器自己所支持的跨域请求: - Access-Control-Allow-Origin: http://foo.example
- Access-Control-Allow-Methods: POST, GET
- Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
- Access-Control-Max-Age: 86400
从名字便可以看出来,分别是支持的源服务器,方法,自定义头,和Preflighted requests的缓存时间。
这样一看解决跨就很简单了,只要我们在response中添加这几条头信息就可以啦。接下来就试试,测试用例是本地服务,前端端口和后台端口不一样,后台是Spring Boot,马上动手试试:
手动设置
手动给response添加这几个Header,看看请求信息:
说明请求成功了,从response headers中也能看到咱们的添加的header信息。
过滤器
一个一个设置太过麻烦,但这是最安全的,可以精准到方法级别,如果想要全部支持跨域,自然想到用过滤器来控制,统一添加header便可;
Spring mvc的@CrossOrigin注解
过滤器好用,但没法精确配置,手动设置又太麻烦,这时候框架的威力就显示出来了,只要在方法加上这个注解,配置@RequestMapping就可以支持跨域了:
3其他方法
除了CORS,还有JSONP和本身就支持跨域的标签,如img,iframe等,这些需要的自己去了解一下。
文章参考了sf的一篇优秀文章,写的更加优秀和详细哦不要再问我跨域的问题了