BUG- 使用自定义Filter不能解决跨域的问题
Access to XMLHttpRequest at 'http://localhost:8080/employee/updateEmployee/' from origin 'http://localhost:63343' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
一般我们会自定义一个拦截器实现登录拦截,使用spring mvc的CorsFilter过滤器解决跨域的问题,然而当你的请求满足了拦截器时,请求继续向下执行,没有问题,但是当你的请求不满足拦截器时,将会出现跨域问题,哪怕你解决了跨域问题都未必有效。
因为自定义的拦截器会在CorsFilter过滤器之前执行,因此会产生跨域问题
这时就可以使用自定义的Filter来解决跨域问题,因为过滤的是servlet的请求,我们的拦截器是spring mvc的拦截器,想要进入spring mvc的拦截器,前提是要进入spring mvc,进入springmvc 是通过dispatcherServler,满足dispatcherServler中设置的请求才能进入,恰巧Filter可以对servlet进行拦截
然而在使用自定义Filter时,要注意两点
1、Tomcat默认不支持restful风格的put与delete请求
这种情况下,我们可以选择使用RequestMapping来接收请求,不使用put、delete;
或者用其他的方式解决(这里我没有仔细去看)
//TODO 标个todo回头在写2、预检请求的问题
概念
规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是
GET
以外的 HTTP 请求,或者搭配某些 MIME 类型的POST
请求),浏览器必须首先使用OPTIONS
方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。简单请求不会触发CORS预检请求,而非简单请求则会触发。若请求满足所有下述条件,则该请求可视为“简单请求”,否则为非简单请求:
- 使用下列方法之一:GET POST HEAD
- Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
Accept
Accept-Language
Content-Language
Content-Type
()DPR
Downlink
Save-Data
Viewport-Width
Width
Content-Type
的值仅限于下列三者之一:
text/plain
multipart/form-data
application/x-www-form-urlencoded
- 请求中的任意
XMLHttpRequestUpload
对象均没有注册任何事件监听器;XMLHttpRequestUpload
对象可以使用XMLHttpRequest.upload
属性访问。- 请求中没有使用
ReadableStream
对象。- 满足上面所有的条件才不会发送预检请求,在实际项目中我们的请求格式可能是
application/json
格式编码,或者使用自定义请求头都会触发CORS的预检请求。也就是说浏览器会判断是否是复杂请求,若是复杂请求,这时浏览器会先发送一个域请求向后台确认,若能请求成功,在发送真正的请求到后台,这里需要注意的是,预检请求是不携带session的,不仅是session还有很多信息都是不携带的,所以使用session存储登录信息做登录拦截的,会遇到跨域问题。
解决方案:
一、干掉预检请求(不推荐)
在拦截器中放过预检请求,这种方式是很不推荐的,就像我看的一篇博客说的,前辈们怕房子不安全,造了个门,而你没有钥匙,于是你便拆了门。
二、把请求转换为简单请求