简体   繁体   中英

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

We have a client api call that requires a post be sent as form-data. When we run the call through Chrome's Postman extension it runs successfully when we specify form-data, and returns an error if we specify x-www-form-urlencoded. This is expected.

However when trying to run in node.js using the "request" npm package to handle the post we continue to receive an error message from the api which unfortunately does not give us specifics as to what is wrong. But we do see that the request header object looks like this when it goes out:

_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',

Our Node.js code looks like:

  //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)
      }
    }
  );

What I am wondering is why the content-type header continues to read "application/x-www-form-urlencoded" when we have provided a content-disposition of 'form-data'. To me it seems like if I could remove the content-type header attribute it should work - but how to do that?

Any insights would be appreciated.

The reason why it is updating the Content-Type header to application/x-www-form-urlencoded is because you are using form in your POST 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) {
  ...
});

In order to handle this, you need to add the content as body as provided below.

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) {
  ...
});

In the end we went with the form-data package found here: https://www.npmjs.com/package/form-data

Our code now looks like this:

    //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});
      }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM