You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

KrakenD转发POST请求时请求体前出现额外数字的原因排查

问题描述

使用KrakenD作为API网关发送POST请求时,后端收到的请求体前多了一个数字。

示例请求:

curl -X POST -H "Content-Type: application/json" -d '{"username":"***","password":"***"}' http://127.0.0.1:8000/api/v1/token

后端收到的请求源:

b'POST /api/v1/token HTTP/1.1\r\nHost: host.docker.internal:8000\r\nUser-Agent: KrakenD Version 2.4.3\r\nTransfer-Encoding: chunked\r\nContent-Type: application/json\r\nX-Forwarded-For: 172.17.0.1\r\nX-Forwarded-Host: 127.0.0.1:8080\r\nAccept-Encoding: gzip\r\n\r\n'
b'23\r\n{"username":"***","password":"***"}\r\n'
b'0\r\n\r\n'

krakend.json配置:

{
  "version": 3,
  "debug_endpoint": true,
  "endpoints": [
    {
      "endpoint": "/api/v1/token",
      "method": "POST",
      "backend": [
        {
          "url_pattern": "/api/v1/token",
          "method": "POST",
          "host": [ "http://host.docker.internal:8000" ]
        }
      ]
    }
  ]
}

直接请求后端时不会出现该前置数字,请问通过KrakenD网关后出现该数字的原因是什么?

原因分析

这个前置数字是HTTP**分块传输编码(Chunked Transfer Encoding)**的一部分,并非KrakenD的异常,而是它默认使用分块编码向后端发送请求导致的。

从后端收到的请求头里能看到Transfer-Encoding: chunked字段,这代表请求体采用分块传输:

  • 23是十六进制数字,对应后续数据块的字节长度(十进制为35,正好是{"username":"***","password":"***"}的字符数)
  • 数据块后的\r\n是分块的分隔符
  • 最后的0\r\n\r\n表示分块传输结束

直接用curl请求后端时,curl会自动处理请求体编码,一般不会使用分块编码(除非请求体极大),所以后端看不到这个数字。如果后端没有正确实现分块编码的解析逻辑,就会把分块长度标识当成请求体的一部分。

要解决这个问题,可在KrakenD的后端配置中添加disable_chunked_encoding: true,强制关闭分块传输,修改后的配置如下:

{
  "version": 3,
  "debug_endpoint": true,
  "endpoints": [
    {
      "endpoint": "/api/v1/token",
      "method": "POST",
      "backend": [
        {
          "url_pattern": "/api/v1/token",
          "method": "POST",
          "host": [ "http://host.docker.internal:8000" ],
          "disable_chunked_encoding": true
        }
      ]
    }
  ]
}

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:13