How is an HTTP POST request made in node.js?

后端 未结 21 2396
南方客
南方客 2020-11-21 23:54

How can I make an outbound HTTP POST request, with data, in node.js?

相关标签:
21条回答
  • 2020-11-22 00:20
    let request = require('request');
    let jsonObj = {};
    request({
        url: "https://myapii.com/sendJsonData",
        method: "POST",
        json: true,
        body: jsonObj
        }, function (error, resp, body){
           console.log(resp);
    });
    

    Or you could use this library:

    let axios = require("axios");
    let jsonObj = {};
    
    const myJsonAPI = axios.create({
       baseURL: 'https://myapii.com',
       timeout: 120*1000
    });
    
    let response = await myJsonAPI.post("sendJsonData",jsonobj).catch(e=>{
        res.json(e);
    });
    console.log(response);
    
    0 讨论(0)
  • 2020-11-22 00:22

    There are dozens of open-source libraries available that you can use to making an HTTP POST request in Node.

    1. Axios (Recommended)

    const axios = require('axios');
    
    const data = {
        name: 'John Doe',
        job: 'Content Writer'
    };
    
    axios.post('https://reqres.in/api/users', data)
        .then((res) => {
            console.log(`Status: ${res.status}`);
            console.log('Body: ', res.data);
        }).catch((err) => {
            console.error(err);
        });
    

    2. Needle

    const needle = require('needle');
    
    const data = {
        name: 'John Doe',
        job: 'Content Writer'
    };
    
    needle('post', 'https://reqres.in/api/users', data, {json: true})
        .then((res) => {
            console.log(`Status: ${res.statusCode}`);
            console.log('Body: ', res.body);
        }).catch((err) => {
            console.error(err);
        });
    

    3. Request

    const request = require('request');
    
    const options = {
        url: 'https://reqres.in/api/users',
        json: true,
        body: {
            name: 'John Doe',
            job: 'Content Writer'
        }
    };
    
    request.post(options, (err, res, body) => {
        if (err) {
            return console.log(err);
        }
        console.log(`Status: ${res.statusCode}`);
        console.log(body);
    });
    

    4. Native HTTPS Module

    const https = require('https');
    
    const data = JSON.stringify({
        name: 'John Doe',
        job: 'Content Writer'
    });
    
    const options = {
        hostname: 'reqres.in',
        path: '/api/users',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': data.length
        }
    };
    
    
    const req = https.request(options, (res) => {
        let data = '';
    
        console.log('Status Code:', res.statusCode);
    
        res.on('data', (chunk) => {
            data += chunk;
        });
    
        res.on('end', () => {
            console.log('Body: ', JSON.parse(data));
        });
    
    }).on("error", (err) => {
        console.log("Error: ", err.message);
    });
    
    req.write(data);
    req.end();
    

    For details, check out this article.

    0 讨论(0)
  • 2020-11-22 00:24

    This my solution for POST and GET.

    About the Post method:

    If the body is a JSON object, so it's important to deserialize it with JSON.stringify and possibly set the Content-Lenght header accordingly:

          var bodyString=JSON.stringify(body)
          var _headers = {
            'Content-Length': Buffer.byteLength(bodyString)
          };
    

    before writing it to the request:

    request.write( bodyString );
    

    About both Get and Post methods:

    The timeout can occur as a socket disconnect, so you must register its handler like:

    request.on('socket', function (socket) {
            socket.setTimeout( self.timeout );
            socket.on('timeout', function() {
                request.abort();
                if(timeout) return timeout( new Error('request timed out') );
            });
        });
    

    while the request handler is

           request.on('timeout', function () {
              // Timeout happend. Server received request, but not handled it
              // (i.e. doesn't send any response or it took to long).
              // You don't know what happend.
              // It will emit 'error' message as well (with ECONNRESET code).
              req.abort();
              if(timeout) return timeout( new Error('request timed out') );
            });
    

    I strongly suggest to register both the handlers.

    The response body is chunked, so you must concat chunks at the data handler:

          var body = '';
          response.on('data', function(d) {
              body += d;
          });
    

    At the end the body will contain the whole response body:

          response.on('end', function() {
            try {
                var jsonResponse=JSON.parse(body);
                if(success) return success( jsonResponse );
            } catch(ex) { // bad json
              if(error) return error(ex.toString());
            }
          });
    

    It is safe to wrap with a try...catchtheJSON.parse` since you cannot be sure that it is a well-formatted json actually and there is no way to be sure of it at the time you do the request.

    Module: SimpleAPI

    /**
     * Simple POST and GET
     * @author Loreto Parisi (loretoparisi at gmail dot com)
    */
    (function() {
    
      var SimpleAPI;
    
      SimpleAPI = (function() {
    
        var qs = require('querystring');
    
        /**
         * API Object model
         * @author Loreto Parisi (loretoparisi at gmail dot com)
         */
        function SimpleAPI(host,port,timeout,ssl,debug,json) {
    
          this.host=host;
          this.port=port;
          this.timeout=timeout;
          /** true to use ssl - defaults to true */
          this.ssl=ssl || true;
          /** true to console log */
          this.debug=debug;
          /** true to parse response as json - defaults to true */
          this.json= (typeof(json)!='undefined')?json:true;
          this.requestUrl='';
          if(ssl) { // use ssl
              this.http = require('https');
          } else { // go unsafe, debug only please
              this.http = require('http');
          }
        }
    
        /**
         * HTTP GET
         * @author Loreto Parisi (loretoparisi at gmail dot com)
         */
        SimpleAPI.prototype.Get = function(path, headers, params, success, error, timeout) {
    
          var self=this;
          if(params) {
            var queryString=qs.stringify(params);
            if( queryString ) {
              path+="?"+queryString;
            }
          }
          var options = {
            headers : headers,
            hostname: this.host,
            path: path,
            method: 'GET'
          };
          if(this.port && this.port!='80') { // port only if ! 80
            options['port']=this.port;
          }
          if(self.debug) {
            console.log( "SimpleAPI.Get", headers, params, options );
          }
          var request=this.http.get(options, function(response) {
    
              if(self.debug) { // debug
                console.log( JSON.stringify(response.headers) );
              }
    
              // Continuously update stream with data
              var body = '';
              response.on('data', function(d) {
                  body += d;
              });
              response.on('end', function() {
                try {
                  if(self.json) {
                    var jsonResponse=JSON.parse(body);
                    if(success) return success( jsonResponse );
                  }
                  else {
                    if(success) return success( body );
                  }
                } catch(ex) { // bad json
                  if(error) return error( ex.toString() );
                }
              });
            });
            request.on('socket', function (socket) {
                socket.setTimeout( self.timeout );
                socket.on('timeout', function() {
                    request.abort();
                    if(timeout) return timeout( new Error('request timed out') );
                });
            });
            request.on('error', function (e) {
              // General error, i.e.
              //  - ECONNRESET - server closed the socket unexpectedly
              //  - ECONNREFUSED - server did not listen
              //  - HPE_INVALID_VERSION
              //  - HPE_INVALID_STATUS
              //  - ... (other HPE_* codes) - server returned garbage
              console.log(e);
              if(error) return error(e);
            });
            request.on('timeout', function () {
              // Timeout happend. Server received request, but not handled it
              // (i.e. doesn't send any response or it took to long).
              // You don't know what happend.
              // It will emit 'error' message as well (with ECONNRESET code).
              req.abort();
              if(timeout) return timeout( new Error('request timed out') );
            });
    
            self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path;
            if(self.debug) {
              console.log("SimpleAPI.Post",self.requestUrl);
            }
            request.end();
        } //RequestGet
    
        /**
         * HTTP POST
         * @author Loreto Parisi (loretoparisi at gmail dot com)
         */
        SimpleAPI.prototype.Post = function(path, headers, params, body, success, error, timeout) {
          var self=this;
    
          if(params) {
            var queryString=qs.stringify(params);
            if( queryString ) {
              path+="?"+queryString;
            }
          }
          var bodyString=JSON.stringify(body)
          var _headers = {
            'Content-Length': Buffer.byteLength(bodyString)
          };
          for (var attrname in headers) { _headers[attrname] = headers[attrname]; }
    
          var options = {
            headers : _headers,
            hostname: this.host,
            path: path,
            method: 'POST',
            qs : qs.stringify(params)
          };
          if(this.port && this.port!='80') { // port only if ! 80
            options['port']=this.port;
          }
          if(self.debug) {
            console.log( "SimpleAPI.Post\n%s\n%s", JSON.stringify(_headers,null,2), JSON.stringify(options,null,2) );
          }
          if(self.debug) {
            console.log("SimpleAPI.Post body\n%s", JSON.stringify(body,null,2) );
          }
          var request=this.http.request(options, function(response) {
    
              if(self.debug) { // debug
                console.log( JSON.stringify(response.headers) );
              }
    
              // Continuously update stream with data
              var body = '';
              response.on('data', function(d) {
                  body += d;
              });
              response.on('end', function() {
                try {
                    console.log("END", body);
                    var jsonResponse=JSON.parse(body);
                    if(success) return success( jsonResponse );
                } catch(ex) { // bad json
                  if(error) return error(ex.toString());
                }
              });
    
            });
    
            request.on('socket', function (socket) {
                socket.setTimeout( self.timeout );
                socket.on('timeout', function() {
                    request.abort();
                    if(timeout) return timeout( new Error('request timed out') );
                });
            });
            request.on('error', function (e) {
              // General error, i.e.
              //  - ECONNRESET - server closed the socket unexpectedly
              //  - ECONNREFUSED - server did not listen
              //  - HPE_INVALID_VERSION
              //  - HPE_INVALID_STATUS
              //  - ... (other HPE_* codes) - server returned garbage
              console.log(e);
              if(error) return error(e);
            });
            request.on('timeout', function () {
              // Timeout happend. Server received request, but not handled it
              // (i.e. doesn't send any response or it took to long).
              // You don't know what happend.
              // It will emit 'error' message as well (with ECONNRESET code).
              req.abort();
              if(timeout) return timeout( new Error('request timed out') );
            });
    
            self.requestUrl = (this.ssl?'https':'http') + '://' + request._headers['host'] + request.path;
            if(self.debug) {
              console.log("SimpleAPI.Post",self.requestUrl);
            }
    
            request.write( bodyString );
            request.end();
    
        } //RequestPost
    
        return SimpleAPI;
    
      })();
    
      module.exports = SimpleAPI
    
    }).call(this);
    

    Usage:

    // Parameters
    // domain: example.com
    // ssl:true, port:80
    // timeout: 30 secs
    // debug: true
    // json response:true
    var api = new SimpleAPI('posttestserver.com', 80, 1000 * 10, true, true, true); 
    
    var headers = {
        'Content-Type' : 'application/json',
        'Accept' : 'application/json' 
    };
    var params = {
      "dir" : "post-test"
    };
    var method = 'post.php';
    
    api.Post(method, headers, params, body
        , function(response) { // success
           console.log( response );
        }
        , function(error) { // error
          console.log( error.toString() );
        }
        , function(error) { // timeout
           console.log( new Error('timeout error') );
        });
    
    0 讨论(0)
  • 2020-11-22 00:25

    request is now deprecated. It is recommended you use an alternative

    In no particular order and dreadfully incomplete:

    • native HTTP/S, const https = require('https');
    • node-fetch
    • axios
    • got
    • superagent
    • bent
    • make-fetch-happen
    • unfetch
    • tiny-json-http
    • needle
    • urllib

    Stats comparision Some code examples

    Original answer:

    This gets a lot easier if you use the request library.

    var request = require('request');
    
    request.post(
        'http://www.yoursite.com/formpage',
        { json: { key: 'value' } },
        function (error, response, body) {
            if (!error && response.statusCode == 200) {
                console.log(body);
            }
        }
    );
    

    Aside from providing a nice syntax it makes json requests easy, handles oauth signing (for twitter, etc.), can do multi-part forms (e.g. for uploading files) and streaming.

    To install request use command npm install request

    0 讨论(0)
  • 2020-11-22 00:25

    Simple and dependency-free. Uses a Promise so that you can await the result. It returns the response body and does not check the response status code.

    const https = require('https');
    
    function httpsPost({body, ...options}) {
        return new Promise((resolve,reject) => {
            const req = https.request({
                method: 'POST',
                ...options,
            }, res => {
                const chunks = [];
                res.on('data', data => chunks.push(data))
                res.on('end', () => {
                    let body = Buffer.concat(chunks);
                    switch(res.headers['content-type']) {
                        case 'application/json':
                            body = JSON.parse(body);
                            break;
                    }
                    resolve(body)
                })
            })
            req.on('error',reject);
            if(body) {
                req.write(body);
            }
            req.end();
        })
    }
    

    Usage:

    async function main() {
        const res = await httpsPost({
            hostname: 'sentry.io',
            path: `/api/0/organizations/org/releases/${changesetId}/deploys/`,
            headers: {
                'Authorization': `Bearer ${process.env.SENTRY_AUTH_TOKEN}`,
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                environment: isLive ? 'production' : 'demo',
            })
        })
    }
    
    main().catch(err => {
        console.log(err)
    })
    
    0 讨论(0)
  • 2020-11-22 00:26

    I use Restler and Needle for production purposes. They are both much more powerful than native httprequest. It is possible to request with basic authentication, special header entry or even upload/download files.

    As for post/get operation, they also are much simpler to use than raw ajax calls using httprequest.

    needle.post('https://my.app.com/endpoint', {foo:'bar'}, 
        function(err, resp, body){
            console.log(body);
    });
    
    0 讨论(0)
提交回复
热议问题