SpringCloud Gateway Header重复导致的问题排查
教程简介
最近在使用SpringCloud Gateway代理业务接口的是出现了响应数据乱码的情况,业务接口有点特殊,是通过OpenResty代理过一次后的对外链接,问题显示如下:
然后通过排除法,不使用OpenResty的业务接口则是正常的,然后对比了一下响应头信息发现如下
那么会不会和这些重复的头信息有关系呢?所以针对发现的问题继续了解
理解Accept,Vary
之前对于请求头里面的参数没有特别注意过,此次在排查问题过程中特意了解了下Accept和Vary的作用。
Accept和Vary是成对出现的,大概意思就是客户端(比如说浏览器或者手机)与服务器之间内容协商的头部关键字信息,一个告诉服务器我要啥,一个告诉客户端我给了啥,一应一答,最终达到客户端需要什么信息服务器就给客户端相应要求的信息,完成一种专业术语叫内容协商的机制。
Accept呢还能具体分为如下几种
1 | Accept: 声明客户端可以处理的资源格式 |
而服务端涉及的常见头部包括:
1 | Content-Type: 指示资源的 MIME 类型 |
大家感兴趣的话可以查看下自己浏览器那些请求和响应,按照这个规律来看看。
理解SpringCloud Gateway Header的内部原理
为了更好的排查此问题和根治此问题,所以特意再去了解了下SpringCloud Gateway内部对于Header的内部处理。
如何解决
通过观察不通过SpringCloud Gateway直接去访问的请求头和响应头信息如下
然后通过SpringCloud Gateway去访问的请求头和响应头信息如下(通过抓包查看网关内部如何去调用业务接口,命令:tcpdump -i any -s 0 -w 1.pcap
)得到文件后使用WireShark打开,如下结果
很明显,在SpringCloud Gateway内部拿到业务接口响应后,对外的响应处理过程中,头部信息进行了重复,这个重复就是罪魁祸首,所以我们需要解决重复问题即可,具体如下:
在SpringCloud Gateway框架中有一个去除重复头的过滤器DedupeResponseHeaderGatewayFilterFactory
该类提供了3种策略处理重复头问题
1 | RETAIN_FIRST: 默认值,保留第一个值 |
所以在我们的项目配置文件添加如下一段配置spring.cloud.gateway.default-filters[0]=DedupeResponseHeader=access-control-allow-credentials access-control-allow-methods set-cookie vary content-encoding, RETAIN_FIRST
将重复的几项写入空格分开,最后以 逗号后面跟一个策略保留值即可。
通过以上的配置再次去调用接口,就正常了,其它接口也是正常的。