request.post 继续覆盖 content-type 为 content-type:application/x-www-form-urlencoded 当指定 form-data 时

request.post continues to override content-type as content-type: application/x-www-form-urlencoded when form-data is being specified

我们有一个客户 api 呼叫需要 post 作为 form-data 发送。当我们 运行 通过 Chrome 的 Postman 扩展调用时,当我们指定 form-data 时它 运行 成功,如果我们指定 [=32] returns 则出错=].这是预期的。

然而,当尝试 运行 在 node.js 中使用 "request" npm 包来处理 post 时,我们继续从 api 不幸的是,这并没有给我们具体的错误信息。但是我们确实看到请求headerobject出去的时候是这样的:

_header: 'POST /api/client/coupon/add HTTP/1.1\r\nAuthorization: Basic [auth string redacted]\r\nhost: beta1.client.com\r\ncontent-type: application/x-www-form-urlencoded\r\ncontent-length: 172\r\nConnection: keep-alive\r\n\r\n',

我们的 Node.js 代码如下所示:

  //Create the coupon
  var coupon = { code: "abcde1234"),
    discount: "33",
    type: "percent"
  }

  var request = require('request');
  request.post(
    {
      url: "https://beta1.client.com/api/coupon/add",
      headers: {
        "authorization": auth,
        "content-disposition": "form-data; name='data'"
      },
      form: coupon
    },

    function (error, response, body) {
      if (!error && response.statusCode == 200) {
        console.log(body)
      }
    }
  );

我想知道的是,为什么 content-type header 在我们提供 'form-data' 的 content-disposition 时继续读取 "application/x-www-form-urlencoded"。对我来说,如果我可以删除 content-type header 属性,它应该可以工作 - 但如何做到这一点?

如有任何见解,我们将不胜感激。

最后我们使用了在这里找到的表单数据包:https://www.npmjs.com/package/form-data

我们的代码现在看起来像这样:

    //create coupon json and stringify it
    var coupon = {
      coupon: {
        code: couponCode,
        discount: discountPercentage,
        type: 'percent',
        product: productId,
        times: 1,
        expires: couponExpiresDt
      }
    };
    var couponString = JSON.stringify(coupon);

    //create form-data object to be posted to client api
    var FormData = require('form-data');
    var couponForm = new FormData();
    couponForm.append('data', couponString);

    //create submission options for the post
    var submitOptions = {
      hostname:config.client_api_host,
      path:'/api/2/coupon/add',
      auth:auth,
      protocol:'https:'
    };

    //submit the coupon/add post request
    couponForm.submit(submitOptions, function(err, res) {
      res.resume();

      if (err) {
        callback(err);
      } else if (res.statusCode != 200) {
        callback(new Error('API createDiscount post response error:', res.statusCode));
      } else {
        logger.log('info', "coupon code " + couponCode +  " has apparently been created");
        callback(null, {coupon_code: couponCode, expires: couponExpiresDt});
      }
    });

之所以将 Content-Type header 更新为 application/x-www-form-urlencoded 是因为您在 POST 请求中使用了 form

request.post({
  url: "https://beta1.client.com/api/coupon/add",
  headers: {
    "authorization": auth,
    "content-disposition": "form-data; name='data'"
  },
  form: coupon
}, function (error, response, body) {
  ...
});

为了处理这个问题,您需要添加下面提供的 body 内容。

request.post({
  url: "https://beta1.client.com/api/coupon/add",
  headers: {
    "authorization": auth,
    "content-disposition": "form-data; name='data'"
  },
  body: coupon
}, function (error, response, body) {
  ...
});