56

What are the steps to send a https request in node js to a rest service? I have an api exposed like (Original link not working...)

How to pass the request and what are the options I need to give for this API like host, port, path and method?

Federico Baù
  • 6,013
  • 5
  • 30
  • 38
vinod
  • 8,350
  • 9
  • 32
  • 36

6 Answers6

80

just use the core https module with the https.request function. Example for a POST request (GET would be similar):

var https = require('https');

var options = {
  host: 'www.google.com',
  port: 443,
  path: '/upload',
  method: 'POST'
};

var req = https.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
zemirco
  • 16,171
  • 8
  • 62
  • 96
  • edited the above - question was about https (!) - we need var https = require('https'); – sebilasse May 27 '16 at 19:00
  • 4
    I exactly do the same but got socket hang up error. it seemed that TLS failed. – MDK Jun 17 '17 at 01:21
  • and either the request module throw same error and when I use SSLv3_methods got SSLv3 disabled error. I really hecked up in sending a normal ssl/tls request with nodejs. – MDK Jun 17 '17 at 01:23
  • Can you please also mention how to send the post data – Rupali Pemare Oct 05 '17 at 06:30
29

The builtin http and https modules are perfectly good if a bit low-level. You'll probably want to use a module that handles the details for you and provides a nice higher-level API.

In node v18, node itself exposes a global fetch(url) method, although as of 2023 it is still considered experimental and subject to change. Also, perhaps surprisingly, node's builtin fetch() global does not use the HTTP stack provided by the traditional builtin http/https modules. Instead, it uses a parallel, from-scratch HTTP stack rewrite called undici.

The builtin fetch() is convenient, but given the instability and that it's still missing a few features, I'd avoid it in production use until the feature is more stable.

There are several popular modules available on npm.

  • request used to be the very popular standard from the very early days of the node ecosystem, but it is no longer maintained, so you shouldn't use it in new work.
  • axios is a very popular and actively maintained HTTP library.
  • node-fetch is another popular option that implements the fetch API.
  • There are hundreds of other options of varying popularity and quality; you might want to compare the available options to see what will meet your particular needs.
josh3736
  • 139,160
  • 33
  • 216
  • 263
29

Note if you are using https.request do not directly use the body from res.on('data',... This will fail if you have a large data coming in chunks. So you need to concatenate all the data and then process the response in res.on('end'. Example -

  var options = {
    hostname: "www.google.com",
    port: 443,
    path: "/upload",
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': Buffer.byteLength(post_data)
    }
  };

  //change to http for local testing
  var req = https.request(options, function (res) {
    res.setEncoding('utf8');

    var body = '';

    res.on('data', function (chunk) {
      body = body + chunk;
    });

    res.on('end',function(){
      console.log("Body :" + body);
      if (res.statusCode !== 200) {
        callback("Api call failed with response code " + res.statusCode);
      } else {
        callback(null);
      }
    });

  });

  req.on('error', function (e) {
    console.log("Error : " + e.message);
    callback(e);
  });

  // write data to request body
  req.write(post_data);
  req.end();
Anatoly
  • 5,056
  • 9
  • 62
  • 136
Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • is there any way I can use https like `https.request(url, options, function (res) {})`. In my case I would fetching the url from mapping otherwise I have to break and again join the url to do the work. – Chitrank Dixit Oct 15 '18 at 13:49
  • 2
    @ChitrankDixit I do not completely understand your use case but you can do that. Take a look at https://nodejs.org/api/https.html#https_https_request_options_callback. You can do `https.request(url[, options][, callback])` – Aniket Thakur Oct 15 '18 at 14:28
5

Using the request module solved the issue.

// Include the request library for Node.js   
var request = require('request');
//  Basic Authentication credentials   
var username = "vinod"; 
var password = "12345";
var authenticationHeader = "Basic " + new Buffer(username + ":" + password).toString("base64");
request(   
{
url : "https://133-70-97-54-43.sample.com/feedSample/Query_Status_View/Query_Status/Output1?STATUS=Joined%20school",
headers : { "Authorization" : authenticationHeader }  
},
 function (error, response, body) {
 console.log(body); }  );         
David
  • 3,166
  • 2
  • 30
  • 51
vinod
  • 8,350
  • 9
  • 32
  • 36
4

Since there isn't any example with a ´GET´ method here is one. The catch is that the path in the options Object should be set to '/' in order to send the request correctly

const https = require('https')
const options = {
  hostname: 'www.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  headers: {
    'Accept': 'plain/html',
    'Accept-Encoding': '*',
  }
}

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`);
  console.log('headers:', res.headers);

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', error => {
  console.error(`Error on Get Request --> ${error}`)
})

req.end()
Welcor
  • 2,431
  • 21
  • 32
Federico Baù
  • 6,013
  • 5
  • 30
  • 38
0

The example using 'GET' method is good but it can also be used with constant variables in TypeScript/Node.js setup. If that's the case, the functions on('error') and end() have to be defined outside of the https.request function.

const https = require('https')
const options = {
  hostname: 'www.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  headers: {
    'Accept': 'plain/html',
    'Accept-Encoding': '*',
  }
}

const request = https.request(options, res => {
  const callback = (data: string) => {
    process.stdout.write(`response data: ${data}`);
  }
  res.on('data', callback)
})

request.on('error', error => {
  console.error(`Error on Get Request --> ${error}`)
})
request.end()
Dave Lee
  • 316
  • 3
  • 9