跨域请求的OPTIONS问题

今天在做项目的时候,有一个问题折腾了大半天。
前后端分离的项目,前端独立启动,端口号为1024;后端为微服务架构,前端部署一个网关服务,端口号7001。前后端都启动以后,前端向后端发送请求属于跨域,在登录完成以后前端会设置请求头Authorization将token带入,但是在后端的过滤器中却发现获取不到Authorization。

问题定位

前端是通过ajax发送的rest请求,将所有可能发生问题的地方逐步注释掉以后,还是没有定位到问题的原因。
没有办法,启动Fiddler,然后模拟发送请求,带入Authorization请求头:

GET http://127.0.0.1:7001/normdb/dbConfig/list HTTP/1.1
User-Agent: Fiddler
Authorization: 123
Host: 127.0.0.1:7001

在IDE中设置断点,拦截请求,查看请求头信息,发现请求头是可以被接收到的。
从上面的分析,判断应该不是后台服务的问题。


然后重新启动前端,发送请求,在Fiddler中抓包分析。奇怪的情况就这么出现了:
请求信息
请求中的授权信息
从上面的两张图看出,Authorization请求头没有被添加到请求中。
老眼昏花看了半天,也没有发现问题所在。过了好长时间才终于发现了端倪,这个被抓包的请求的请求方法是OPTIONS,但是我前端明明使用的是GET的ajax方法。
直觉告诉我,这应该就是问题所在!!

OPTIONS分析

度娘一把,果然你所踩到的坑前辈们都已经踩过了。
W3C规范:跨域请求中,分为简单请求和复杂请求;所谓的简单请求,需要满足如下几个条件:
- GET,HEAD,POST请求中的一种;
- 除了浏览器在请求头上增加的信息(如Connection,User-Agent等),开发者仅可以增加Accept,Accept-Language,Content-Type等;
- Content-Type的取值必须是以下三个:application/x-www-form-urlencoded,multipart/form-data,text/plain。


在发出复杂请求的之前,就会出现一次OPTIONS请求。
OPTIONS请求可以被称作一次嗅探请求,通过这个方法,客户端可以在采取具体的资源请求之前,决定对资源采取何种必要措施。
由于我的问题出现在请求内容为json的时候,所以是复杂请求,提前进行了一次OPTIONS请求。
这个OPTIONS请求中没有增加我们的Authorization请求头,所以就无法通过我们的网关,在网管的地方被拦截下来了,返回了401。

解决办法

目前的项目中,不需要考虑的太复杂,简单处理就是放行OPTIONS请求。
在普通Filter中先通过request获取到method,然后判断OPTIONS后放行;
在ZuulFilter的shouldFilter中,判断OPTIONS直接返回false即可。

会者不难,难者不会!!

猜你喜欢

转载自blog.csdn.net/achang07/article/details/79380990