springboot cors跨域问题,为什么用interceptor拦截部到OPTIONS请求?

springboot cors跨域问题,为什么用interceptor拦截部到OPTIONS请求?

关于什么是cors就不多说了,有很多不错的文章

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/AccesscontrolCORS

https://www.cnblogs.com/yuansc/p/9076604.html

笔者并没有完全用网上提供的方法来处理。没有用springboot默认支持的cors的处理办法。 而是选择用spring的拦截器来拦截OPTIONS请求。

在拦截器的preHandle方法中对OPTIONS请求做了拦截处理,判断如果是OPTIONS请求就会设置响应的响应头

经过测试拦截器拦截不到OPTIONS请求,换句话说就是OPTIONS请求还没走到拦截器就返回了。 

这里就需要了解一下一个请求到拦截器经历了哪些步骤,OPTIONS请求是在那一步就返回了。

大概的步骤如下

request ---> filter(过滤器)----> dispatcherservelet的doservice方法 ----> interceptoor拦截器

既然请求没走到拦截器,我没有没有写过滤器,所以肯定是在doservice方法或者在filter到doservice方法之间就被返回了。

带着问题来看源码,我们来找到服务器容器是在那里处理OPTIONS请求的

于是找到了FrameworkServlet类中有一个doOptions方法,实际上这个方法的调用是在dispatcherservlet的doservice方法之前的,调用processRequest(request, response);方法才会走到doservice方法。


这个方法里判断了 this.dispatchOptionsRequest || CorsUtils.isPreFlightRequest(request)


this.dispatchOptionsRequest默认是false的,所以来看CorsUtils.isPreFlightRequest(request)

这个方法又会调用三个判断条件 其中:

- isCorsRequest方法如下:就判断了request的消息头中是否包含orgin这个消息头 


 - HttpMethod.OPTIONS.matches(request.getMethod())判断这个请求是否是OPTIONS请求

- request.getHeader(HttpHeaders.ACCESSCONTROLREQUEST_METHOD) != null就更直观,直接判断消息头是否有Access-Control-Request-Method这个消息头 


所以现在问题就是是否这三个条件都满足,CorsUtils.isPreFlightRequest(request)返回结果为true,才会走到doservice方法。

经排查,是因为前端没有设置orgin和Access-Control-Request-Method这两个消息头 设置上这两个消息头就可以顺利走到拦截器,并且成功设置cors消息头

问题到这里就解决的,但是其实如果一开始就在过滤器filter中来处理,就不会有这个问题了。doOptions方法是在拦截器之后的。无论设不设消息头都可以成功设置消息头

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容