timothym
timothym

Reputation: 3275

Node HTTPS Request – MalformedJsonException

I'm trying to make a POST request using node/HTTPS, but I keep getting this error:

BODY: {"message":"MalformedJsonException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 11 path $","mdcKey":""}

Here's the code that initiates the request:

  const https = require('https');

  const querystring = require('querystring');

  const POSTData = querystring.stringify({
    'addressTo': '[email protected]',
    'subject': 'testing your email template',
    'templateName': 'genericTemplate',
    'bodyText': 'this is a test'
  });

  console.log(POSTData);

  const HTTPOptions = {
    hostname: 'url.com',
    port: 00000,
    path: '/path',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    }
  };

  const HTTPSrequest = https.request(HTTPOptions, (response) => {
    console.log(`STATUS: ${res.statusCode}`);
    console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
    response.setEncoding('utf8');
    response.on('data', (chunk) => {
      console.log(`BODY: ${chunk}`);
    });
    response.on('end', () => {
      console.log('No more data in response.');
    });
  });

  HTTPSrequest.on('error', (error) => {
    console.log(`problem with request: ${error}`);
  });

  // write data to request body
  HTTPSrequest.write(POSTData);
  HTTPSrequest.end();

I'm assuming it's the POSTData that is the "malformed JSON", here's what it looks like stringified:

addressTo=name%40companyname.com&subject=testing%20your%20email%20template&templateName=genericTemplate&bodyText=this%20is%20a%20test

I'm not sure what I'm doing that is causing the malformed JSON. What am I missing?

Upvotes: 1

Views: 650

Answers (3)

Holly
Holly

Reputation: 1

JsonReader.setLenient(true) to accept malformed JSON at line 1 column 11 path $","mdcKey":""}

Upvotes: -1

Sayuri Mizuguchi
Sayuri Mizuguchi

Reputation: 5330

Help more with explication from @mscdex

Your options object after querystring.stringify has returned. Otherwise you won't know the length of the stringified body data.

It is important to note that you need two extra headers in your options object in order to make a successful post request. These are :

'Content-Type': 'application/json',
'Content-Length': POSTData.length

Check example:

  const HTTPOptions = {
    hostname: 'url.com',
    port: 00000,
    path: '/path',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',          
      'Content-Length': POSTData.length
    }
  };

You can see this examples too: 1st post.

Upvotes: 1

mscdex
mscdex

Reputation: 106696

You're sending an application/x-www-form-urlencoded payload but telling the server it's application/json. The server is complaining because of this mismatch.

The simple solution should be to just change querystring.stringify to JSON.stringify.

You may also need to specify a Content-Length header since some servers may not support chunked requests (which is the default in node). If you do add this, make sure you use Buffer.byteLength(POSTData) as the header value instead of just POSTData.length since the former works for multi-byte characters and the latter returns the number of characters (not bytes).

Upvotes: 2

Related Questions