Nova
Nova

Reputation: 2120

How do I make a https post in Node Js without any third party module?

I'm working on a project that requires https get and post methods. I've got a short https.get function working here...

const https = require("https");

function get(url, callback) {
    "use-strict";
    https.get(url, function (result) {
        var dataQueue = "";    
        result.on("data", function (dataBuffer) {
            dataQueue += dataBuffer;
        });
        result.on("end", function () {
            callback(dataQueue);
        });
    });
}

get("https://example.com/method", function (data) {
    // do something with data
});

My problem is that there's no https.post and I've already tried the http solution here with https module How to make an HTTP POST request in node.js? but returns console errors.

I've had no problem using get and post with Ajax in my browser to the same api. I can use https.get to send query information but I don't think this would be the correct way and I don't think it will work sending files later if I decide to expand.

Is there a small example, with the minimum requirements, to make a https.request what would be a https.post if there was one? I don't want to use npm modules.

Upvotes: 124

Views: 218140

Answers (4)

Fattie
Fattie

Reputation: 12296

Thank goodness, node-fetch is here,

everything else is ancient history.

const fetch = require('node-fetch');
// note: use npm install [email protected] to be able to use "require"

console.log("trying ...")

let body = {
    "ids": ["4e4e4e4e-4e4e-4e4e-4e4e-4e4e4e4e4e4e"]
};

fetch('https://blahblah.com/blah', {
    method: 'POST',
    body: JSON.stringify(body),
    headers: {
        'accept': 'application/json',
        'x-api-key': 'superamazingsecretcryptostuff',
        'Content-Type': 'application/json'
        // fyi, NO need for content length
    }
})
    .then(res => res.json())
    .then(json => console.log(json))
    .catch (err => console.log(err))

console.log("done....")

Job done.

Upvotes: 7

Abolfazl Roshanzamir
Abolfazl Roshanzamir

Reputation: 14892

In Node.js 18 and above

Say goodbye to the node-fetch package ,axios and request ,... now the fetch API is available on the global scope by default.

POST REQUEST

app.get('/', (req, res, next) => {
    // Make a post Request.
    
    fetch('https://jsonplaceholder.typicode.com/posts', {
        method: 'POST',
        body: JSON.stringify({
            title: 'foo',
            body: 'bar',
            userId: 1,
        }),
        headers: {
            'Content-type': 'application/json; charset=UTF-8',
        },
    })
        .then((response) => response.json())
        .then((json) => console.log(json))
        .catch(error => {
            console.log(error)
        })

    res.send('Fetch API is available on the global scope by default')
})

GET REQUEST

const res = await fetch('https://nodejs.org/api/documentation.json');
if (res.ok) {
  const data = await res.json();
  console.log(data);
}

We can make requests as we do in browsers.

For More Information

Upvotes: 24

Max Ivanov
Max Ivanov

Reputation: 6591

Here's a version slightly different from the accepted answer:

  • @returns Promise
  • You can pass the URL directly (no need to split to hostname, path, port)
  • It handles error HTTP status codes
  • It handles connection timeouts
  • For an alternative content type example, it sends JSON instead of x-www-form-urlencoded
const https = require('https')

function post(url, data) {
  const dataString = JSON.stringify(data)

  const options = {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': dataString.length,
    },
    timeout: 1000, // in ms
  }

  return new Promise((resolve, reject) => {
    const req = https.request(url, options, (res) => {
      if (res.statusCode < 200 || res.statusCode > 299) {
        return reject(new Error(`HTTP status code ${res.statusCode}`))
      }

      const body = []
      res.on('data', (chunk) => body.push(chunk))
      res.on('end', () => {
        const resString = Buffer.concat(body).toString()
        resolve(resString)
      })
    })

    req.on('error', (err) => {
      reject(err)
    })

    req.on('timeout', () => {
      req.destroy()
      reject(new Error('Request time out'))
    })

    req.write(dataString)
    req.end()
  })
}

const res = await post('https://...', data)

Upvotes: 55

aring
aring

Reputation: 3602

For example, like this:

const https = require('https');

var postData = JSON.stringify({
    'msg' : 'Hello World!'
});

var options = {
  hostname: 'posttestserver.com',
  port: 443,
  path: '/post.php',
  method: 'POST',
  headers: {
       'Content-Type': 'application/x-www-form-urlencoded',
       'Content-Length': postData.length
     }
};

var 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', (e) => {
  console.error(e);
});

req.write(postData);
req.end();

Upvotes: 253

Related Questions