拦截器的错误配置导致前端正常请求被拦截重定向

写在前面

原本的标题是“HTTP访问控制(CROS) 初识”,但是我发现写的内容其实就是mozilla开发文档里关于CROS里的内容。所以我想我应该记下自己为什么去了解关于CROS的内容。

起因

前端写的一个普通的Post请求,他和我说请求返回302了。我感到很奇怪,我自己用Postman调试都已经通过了,应该是没有问题的。随后前端和我说访问该模块的所有类型 content typeapplication/json 的Post请求都会被302重定向。我怀疑可能是被拦截器拦截了。

在拦截器里打印了下log,发现确实是被拦截器拦截了,原因是请求没有Session信息,而且这些请求都是OPTIONS的方法。就去了解了到了这是和HTTP里CROS相关的内容。

HTTP请求的OPTIONS方法

在HTTP中所有的复杂请求,游览器都会发送一个预检请求到服务器,以获知服务器是否允许该实际请求(Postman中并不会发送预检请求所以没有被服务器拦截)。所以就算前端没有存在跨域,但是请求还是会被后台拦截并被重定向了。

解决方法

在拦截器中对拦截的方法进行判断,对于一些不需要进行拦截的请求直接返回true。


CROS是什么

跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

什么时候会进行CROS

  • 由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求
  • Web 字体 (CSS 中通过 @font-face 使用跨域字体资源)
  • WebGL 贴图
  • 使用 drawImage 将 Images/video 画面绘制到 canvas
  • 样式表(使用 CSSOM)

XHR ( XMLHttpRequest ) 是一个对象,可以和服务器交互。在 Ajax 中被大量使用。Fetch是ES6中的一个新内容。

哪些请求需要发送预检请求

当请求满足下述任一条件时,即应首先发送预检请求:

  • 使用了下面任一 HTTP 方法:
    • PUT
    • DELETE
    • CONNECT
    • OPTIONS
    • TRACE
    • PATCH
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
    • 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
  • 请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
  • 请求中使用了ReadableStream对象。