content-encoding: utf-8🤔
Content-Encoding 是一个实体消息首部,用于对特定媒体类型的数据进行压缩。当这个首部出现的时候,它的值表示消息主体进行了何种方式的内容编码转换。这个消息首部用来告知客户端应该怎样解码才能获取在 Content-Type 中标示的媒体类型内容
今天有个同事对接第三方支付时,遇到一个很有趣的问题:
『对于第三方返回的支付回调信息,系统无法解析。提示错误 Error: Unsupported Content-Encoding: utf-8
』
第一反应是没有按第三方要求的格式提供回调接口,可一看对方需求:
业务方提供 post application/json 的回调地址
这太常用了,系统完全支持,问题肯定不在这。结合报错,然后看了下收到消息头,很有趣的是发现 header 中塞入了: Content-Encoding: utf-8
MDN 上关于 Content-Encoding 的解释如引文所说,这是标识媒体编码方式的,可选指令包括:
- gzip
- compress
- deflate
- identity
- br
从定义也能看出,utf-8
放在这里是不合适的。然后求教了一下大佬,github、stackoverflow 找了一圈,确认这样做是无意义的,并且理论上就是会返回 415 状态。然后同事带着满满自信去找对方反馈,对方很自信地贴出了头部设置代码:
|
|
application/json;encoding=utf-8
是什么?是想表达 content-type: application/json; charset=utf-8
的意思吗?
然后因为对方服务器的稳定性,需要我们这边做处理,向渠道大佬低头…
简单说说同事最后的处理:主要问题还是 koa-bodyparser
中间件处理消息时,其中引用 co-body
库发现头部 content-encoding
值为 utf-8
自然抛出了 415 状态,简单贴一下代码:
|
|
看到有人在使用 express 时也有过类似问题,并且提过 pr 给底层库,但是作者回应这并不属于 bug(这确实是个正经逻辑🤔),那么有两种简单的解决办法:
- 修改底层依赖库代码,上面贴的头部判断部分对 utf-8 直接返回数据
- 增加全局中间件,对每一次请求去掉头部
Content-Encoding
参数,再丢给后面中间件解析消息
虽然不是很麻烦的改动,却是很妥协的处理。最后: