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存储登录信息做登录拦截的,会遇到跨域问题。

解决方案:

  一、干掉预检请求(不推荐)

  在拦截器中放过预检请求,这种方式是很不推荐的,就像我看的一篇博客说的,前辈们怕房子不安全,造了个门,而你没有钥匙,于是你便拆了门。

  二、把请求转换为简单请求

 

posted @ 2021-06-19 20:58  mini9264  阅读(323)  评论(0)    收藏  举报