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

Postman转k6脚本后Content-Type未更新致请求报错排查

问题:Postman转k6脚本后POST请求报"POST body missing"错误

前提

Postman中对应的请求可正常运行。

执行的操作

  • 运行postman-to-k6转换命令:
    postman-to-k6 loadTest.postman_collection.json -o k6-script.js
    
  • 带HTTP调试参数执行k6脚本:
    k6 run --out csv=test_results.csv k6-script.js --http-debug="full"
    

自动生成的k6脚本

// Auto-generated by the postman-to-k6 converter
export let options = { maxRedirects: 4 };

const Request = Symbol.for("request");
postman[Symbol.for("initial")]({
  options
});

export default function() {
  postman[Request]({
    name: "Campaigns",
    id: "189fa369-87c7-4dcb-bf9d-e812d4efd6e8",
    method: "POST",
    address: "https://api.beta.detail-page.journeys.a2z.com/graphql",
    data:
      '{"query":"\n        query campaigns($projectId: ID!) {\n            campaigns(projectId: $projectId) {\n                id\n                createdAt\n                createdBy\n                typeId\n                originalPodData\n                useReactAppUrl\n            }\n        }\n        ","variables":{"projectId":"ghost:PublishTest 2:US"}}',
    headers: {
      "Content-Type": "application/json",
      identitytoken: <Backend-JWT-Token>
    },
    auth(config, Var) {
      const address = new URI(config.address);
      const options = {
        method: "POST",
        protocol: address.protocol(),
        hostname: address.hostname(),
        port: address.port(),
        path: address.path() + address.search(),
        body: config.data,
        region: "us-west-2",
        service: <Service-Name>
      };
      const credential = {
        accessKeyId: <accessKey-ID>,
        secretAccessKey: <Secret-key>,
        sessionToken: <Session-token>
      };
      const signed = aws4.sign(options, credential);
      const [path, query = ""] = signed.path.split("?");
      config.address = new URI()
        .protocol(address.protocol())
        .hostname(signed.hostname)
        .path(path)
        .query(query)
        .toString();
      Object.assign(config.headers, signed.headers);
    }
  });
}

请求日志

POST /graphql HTTP/1.1
Host: api.beta.detail-page.journeys.a2z.com
User-Agent: k6/0.40.0 (https://k6.io/)
Content-Length: 354
Authorization: AWS4-HMAC-SHA256 Credential=ASIAVGC47R5TZOZXHHNM/20221025/us-west-2/execute-api/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token, Signature=9dceffc3e3376fd6f9b860025ce9a82454f740bd189ffa8da3c0a6d8d83e230f
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Identitytoken: <Identity-token>
X-Amz-Date: 20221025T200827Z
X-Amz-Security-Token: <Security-token>
Accept-Encoding: gzip

响应日志

HTTP/2.0 500 Internal Server Error
Content-Length: 61
Access-Control-Allow-Origin: *
Content-Type: text/html; charset=utf-8
Date: Tue, 25 Oct 2022 20:08:27 GMT
Etag: W/"3d-hTSca7jJI4XwK3C0Li5aF8JIkvc"
X-Amz-Apigw-Id: ak9JUEu-PHcFefQ=
X-Amzn-Remapped-Connection: close
X-Amzn-Remapped-Content-Length: 61
X-Amzn-Remapped-Date: Tue, 25 Oct 2022 20:08:27 GMT
X-Amzn-Requestid: bee58104-704c-4cb0-9ec4-399e6f69450d
X-Amzn-Trace-Id: Root=1-6358423b-5dc39ed81536364944f6bd11
X-Powered-By: Express

错误提示

POST body missing. Did you forget use body-parser middleware? group= iter=0 request_id=ad10989c-1023-46c9-5f34-e381a7d5795b scenario=default source=http-debug vu=1


问题分析

从请求日志可见,实际发送的Content-Type被篡改成了application/x-www-form-urlencoded,但脚本里明明配置了application/json。根源在AWS签名流程:

  1. aws4.sign方法若未收到明确的Content-Type,会默认设置为application/x-www-form-urlencoded
  2. 后续Object.assign(config.headers, signed.headers)用签名后的头部覆盖了原配置,导致正确的Content-Type丢失

服务器因Content-Type不匹配,无法解析JSON格式的请求体,因此抛出"POST body missing"错误。

解决方法

修改脚本中的auth函数,在签名配置里明确指定Content-Type,并在签名完成后强制保留正确的头部:

auth(config, Var) {
  const address = new URI(config.address);
  const options = {
    method: "POST",
    protocol: address.protocol(),
    hostname: address.hostname(),
    port: address.port(),
    path: address.path() + address.search(),
    body: config.data,
    region: "us-west-2",
    service: <Service-Name>,
    // 新增:将原请求的Content-Type加入签名配置
    headers: {
      "Content-Type": config.headers["Content-Type"]
    }
  };
  const credential = {
    accessKeyId: <accessKey-ID>,
    secretAccessKey: <Secret-key>,
    sessionToken: <Session-token>
  };
  const signed = aws4.sign(options, credential);
  const [path, query = ""] = signed.path.split("?");
  config.address = new URI()
    .protocol(address.protocol())
    .hostname(signed.hostname)
    .path(path)
    .query(query)
    .toString();
  Object.assign(config.headers, signed.headers);
  // 强制覆盖Content-Type,确保最终发送的是application/json
  config.headers["Content-Type"] = "application/json";
}

修改后重新运行k6脚本,请求日志中的Content-Type会变为application/json,服务器就能正确解析请求体,错误将消失。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:25:21