请求在 NodeJS 中不起作用,但在 Python 中起作用

Request not working in NodeJS but working in Python

以下代码摘自 Postman,我在其中得到了回复。由于某种原因,NodeJS 版本似乎不是 运行 并给出“套接字挂起”错误,而 python 版本运行良好。两个代码都粘贴在下面:

const obj = {
  asset: [
    {
      age: "33",
      existingDisease: false,
      gender: "MALE",
      id: "883a8cb5446f4d6780db2e59bdf4ee35",
      proposerRelationShip: "SELF",
      used: false,
    },
  ],
  cover: [],
  pinCode: "122001",
  quoteId: "7637d7ff982145569fbfa604e3b74485",
  sumInsured: "700000",
  term: { unit: "YEAR", value: "1" },
};

const strObj = JSON.stringify(obj);

var options = {
  method: "POST",
  url: "https://sa.navi.com/v3/premium?paymentMode=SUBSCRIPTION",
  headers: {
    appversion: "2.2.4",
    appversioncode: "92",
    osversion: "Android_11",
    deviceid: "3e44626c3bb37d4c",
    defaultlocale: "en_US",
    "x-session-token": "d635eb15-10aa-4315-9122-6ed3627dc1b8",
    "x-click-stream-data":
      '{"app":{"name":"Navi","version":"92","version_name":"2.2.4"},"device":{"device_id":"3e44626c3bb37d4c","advertising_id":"706649fa-50f0-410d-9c17-3085201808e2","manufacturer":"Google","model":"sdk_gphone_x86","os":"Android","os_version":"30"},"network":{"carrier":"Android","type":"Wifi"},"location":{"latitude":"37.4219983","longitude":"-122.084"},"user":{}}',
    "x-target": "GI",
    source: "APK",
    "content-type": "application/json; charset=utf-8",
    "content-length": "419",
    "accept-encoding": "gzip",
    "user-agent": "okhttp/4.9.0",
  },
  body: strObj,
};

console.log("Going to trigger API");
console.log(options);
request(options, function (error, response) {
  if (error) throw new Error(error);
  console.log(response.body);
});

给出错误:

错误:错误:套接字挂起[=13​​=]

虽然 Python 中的相同代码有效:


url = "https://sa.navi.com/v3/premium?paymentMode=SUBSCRIPTION"

payload = "{\"asset\":[{\"age\":\"33\",\"existingDisease\":false,\"gender\":\"MALE\",\"id\":\"883a8cb5446f4d6780db2e59bdf4ee35\",\"proposerRelationShip\":\"SELF\",\"used\":false}],\"cover\":[],\"pinCode\":\"122001\",\"quoteId\":\"7637d7ff982145569fbfa604e3b74485\",\"sumInsured\":\"700000\",\"term\":{\"unit\":\"YEAR\",\"value\":\"1\"}}"
headers = {
  'appversion': '2.2.4',
  'appversioncode': '92',
  'osversion': 'Android_11',
  'deviceid': '3e44626c3bb37d4c',
  'defaultlocale': 'en_US',
  'x-session-token': 'd635eb15-10aa-4315-9122-6ed3627dc1b8',
  'x-click-stream-data': '{"app":{"name":"Navi","version":"92","version_name":"2.2.4"},"device":{"device_id":"3e44626c3bb37d4c","advertising_id":"706649fa-50f0-410d-9c17-3085201808e2","manufacturer":"Google","model":"sdk_gphone_x86","os":"Android","os_version":"30"},"network":{"carrier":"Android","type":"Wifi"},"location":{"latitude":"37.4219983","longitude":"-122.084"},"user":{}}',
  'x-target': 'GI',
  'source': 'APK',
  'content-type': 'application/json; charset=UTF-8',
  'content-length': '419',
  'accept-encoding': 'gzip',
  'user-agent': 'okhttp/4.9.0'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

你的 content-length 是错误的(你传递的是 419,而你的负载 JSON 的实际长度是 279)。这可能意味着接收服务器仍在等待其余内容到达,它永远不会到达,所以最终服务器超时并挂断你(因此你会收到挂断错误)。

而且,你瞧,当我删除 content-length header 并让请求库自动计算它时,请求开始为我工作。

至于 python 实现,一种猜测是它正在覆盖错误的 content-length 并为您修复它。


仅供参考,request() 库已 deprecated and it is not recommended that people write new code with it as it will not be advanced with new features in the future. A list of suggested alternatives (that all support promises) is here。该列表中我最喜欢的是 got(),它也支持大多数与 request() 库相同的选项,但 promise-based 是核心,并且有许多 API 改进使其更易于使用(在我看来)。

而且,您的代码确实可以与 got() 库一起正常工作(在删除不正确的 content-length header 之后)。

const got = require('got');

const obj = {
    asset: [{
        age: "33",
        existingDisease: false,
        gender: "MALE",
        id: "883a8cb5446f4d6780db2e59bdf4ee35",
        proposerRelationShip: "SELF",
        used: false,
    }, ],
    cover: [],
    pinCode: "122001",
    quoteId: "7637d7ff982145569fbfa604e3b74485",
    sumInsured: "700000",
    term: { unit: "YEAR", value: "1" },
};

const strObj = JSON.stringify(obj);

var options = {
    method: "POST",
    url: "https://sa.navi.com/v3/premium?paymentMode=SUBSCRIPTION",
    headers: {
        appversion: "2.2.4",
        appversioncode: "92",
        osversion: "Android_11",
        deviceid: "3e44626c3bb37d4c",
        defaultlocale: "en_US",
        "x-session-token": "d635eb15-10aa-4315-9122-6ed3627dc1b8",
        "x-click-stream-data": '{"app":{"name":"Navi","version":"92","version_name":"2.2.4"},"device":{"device_id":"3e44626c3bb37d4c","advertising_id":"706649fa-50f0-410d-9c17-3085201808e2","manufacturer":"Google","model":"sdk_gphone_x86","os":"Android","os_version":"30"},"network":{"carrier":"Android","type":"Wifi"},"location":{"latitude":"37.4219983","longitude":"-122.084"},"user":{}}',
        "x-target": "GI",
        source: "APK",
        "content-type": "application/json; charset=utf-8",
        "accept-encoding": "gzip",
        "user-agent": "okhttp/4.9.0",
    },
    body: strObj,
};

console.log("Going to trigger API");
got(options).then(response => {
    console.log(response.body);
}).catch(e => {
    console.log(e);
});