Як здійснюється HTTP POST-запит у node.js?


946

Як я можу зробити вихідний HTTP POST-запит із даними в node.js?


16
Як пропонується у відповіді Джеда Уотсона , я настійно рекомендую використовувати запит, якщо ви не пишете API низького рівня.
namuol

4
Ви можете просто використовувати, node-fetchякий є реалізацією нативного fetchметоду JavaScript, щоб робити HTTP-запити.
Фес Враста

Ця публікація охоплює основні сценарії використання запиту. blog.modulus.io/node.js-tutorial-how-to-use-request-module
Shaswat Rungta

Відповіді:


855

Ось приклад використання node.js для подання POST-запиту в API компілятора Google:

// We need this to build our post string
var querystring = require('querystring');
var http = require('http');
var fs = require('fs');

function PostCode(codestring) {
  // Build the post string from an object
  var post_data = querystring.stringify({
      'compilation_level' : 'ADVANCED_OPTIMIZATIONS',
      'output_format': 'json',
      'output_info': 'compiled_code',
        'warning_level' : 'QUIET',
        'js_code' : codestring
  });

  // An object of options to indicate where to post to
  var post_options = {
      host: 'closure-compiler.appspot.com',
      port: '80',
      path: '/compile',
      method: 'POST',
      headers: {
          'Content-Type': 'application/x-www-form-urlencoded',
          'Content-Length': Buffer.byteLength(post_data)
      }
  };

  // Set up the request
  var post_req = http.request(post_options, function(res) {
      res.setEncoding('utf8');
      res.on('data', function (chunk) {
          console.log('Response: ' + chunk);
      });
  });

  // post the data
  post_req.write(post_data);
  post_req.end();

}

// This is an async file read
fs.readFile('LinkedList.js', 'utf-8', function (err, data) {
  if (err) {
    // If this were just a small part of the application, you would
    // want to handle this differently, maybe throwing an exception
    // for the caller to handle. Since the file is absolutely essential
    // to the program's functionality, we're going to exit with a fatal
    // error instead.
    console.log("FATAL An error occurred trying to read in the file: " + err);
    process.exit(-2);
  }
  // Make sure there's data before we post it
  if(data) {
    PostCode(data);
  }
  else {
    console.log("No data to post");
    process.exit(-1);
  }
});

Я оновив код, щоб показати, як розміщувати дані з файлу замість твердо кодованого рядка. Для цього використовується команда async fs.readFile, розміщуючи фактичний код після успішного читання. Якщо є помилка, вона викидається, а якщо немає даних, процес виходить із від’ємним значенням, щоб вказати на помилку.


4
Чи правильно розраховано заголовок довжини вмісту? Мабуть, це байти, правда?
Ерік

7
Зверніть увагу, що querystring.stringify() не підтримує вкладені об'єкти , тому ви можете використовувати qs.stringify()замість цього.
johndodo

51
Content-Lengthє байтами, а не обов'язково довжиною рядка (UTF-16 тощо). Використання Buffer.byteLength(data)завжди буде правильним.
greenimpala

4
для надсилання стандартних поштових даних об’єктом в querystring.stringifyповинен бути ваш власний об'єкт даних, а не барахло, яке відображається у цій відповіді (що може бути корисно для файлових об’єктів?). Я на цьому вік застряг ... stackoverflow.com/questions/9768192/… забезпечив моє повне рішення
RozzA

7
Поняття: Якщо ви використовуєте зашифрований ssl сайт, вам знадобиться бібліотека "https". Ви не можете просто змінити порт на 443.
Дейв Коллінз

1137

Це стає набагато простіше, якщо ви використовуєте бібліотеку запитів .

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

Окрім надання симпатичного синтаксису, він робить запити json легкими, обробляє підпис під oauth (для твіттера і т. Д.), Може робити багатоскладові форми (наприклад, для завантаження файлів) та потокове передавання.

Для встановлення запиту використовуйте команду npm install request


153
{form: {key: 'value'}} слід замінити на {json: {key: 'value'}} (оскільки питання не стосується форм). Слід також зрозуміти, що "форма" та "json" - це ключові слова бібліотеки запитів, а не частина користувацьких даних (настільки тривіально, як міг би з’явитися цей останній коментар, мені знадобилося певний час, щоб зрозуміти це ...)
blacelle,

7
Я продовжую повертатися до цього питання та відповіді. Це справді має бути "" "відповіддю на питання.
Спенсер Кормос

6
Ви заслуговуєте золотий знак суто за цю відповідь. Це набагато корисніше, ніж прийняте ... а воно існувало ще у 2012 році? Вау
Золтан Шмідт

3
Вам може знадобитися додати залежність, виконавши цю команду "npm install - зберегти запит"
Shady Sherif

18
Ця бібліотека застаріла.
Еворлор

138

Ви можете використовувати бібліотеку запитів. https://www.npmjs.com/package/request

var request = require('request');

Щоб опублікувати дані JSON:

var myJSONObject = { ... };
request({
    url: "http://josiahchoi.com/myjson",
    method: "POST",
    json: true,   // <--Very important!!!
    body: myJSONObject
}, function (error, response, body){
    console.log(response);
});

Щоб розмістити дані XML:

var myXMLText = '<xml>...........</xml>'
request({
    url: "http://josiahchoi.com/myjson",
    method: "POST",
    headers: {
        "content-type": "application/xml",  // <--Very important!!!
    },
    body: myXMLText
}, function (error, response, body){
    console.log(response);
});

Після огляду в їх документації. він констатує наступне: json - встановлює body, але JSON подання значення та додає Тип вмісту: заголовок application / json. Крім того, аналізує орган відповіді як JSON. Це означає, що коли json = true, він встановить заголовок, json та body. В іншому випадку не встановлено заголовок, і розбираємо як текст. (Як і вищенаведений приклад XML). Це робить API запиту зручним і спрощеним, але досить важким для розуміння.
Джосія Чой

Це технічно в їхніх документах, але жоден із прикладів цього не показує - лише форма даних. Це голка в копиці сіна, і, як така, це величезне упущення, оскільки це другий за частотою спосіб я використовую аякс в JS, коли-небудь, і, безумовно, один з найпоширеніших в Інтернеті.
Кайл Бейкер

Використовувати request.post є IMO дещо приємніше, ніж вказувати POST як метод. Ось кілька прикладів від GitHub для використання request.post
drorw

12
Ця бібліотека застаріла.
Еворлор

44

Я використовую Restler і Needle для виробничих цілей. Вони обидва набагато потужніші, ніж рідні httprequest. Можна подати запит за допомогою базової автентифікації, спеціального введення заголовка або навіть завантаження / завантаження файлів.

Що стосується операції "post / get", вони також набагато простіші, ніж необроблені дзвінки ajax за допомогою httprequest.

needle.post('https://my.app.com/endpoint', {foo:'bar'}, 
    function(err, resp, body){
        console.log(body);
});

Я спробував запит, дані вузла-форми та суперагент перед голкою. голка була єдиною, яка працювала правильно для мене, коли я намагався зробити завантаження файлів з декількома формами.
Пол Янг

35

Простий і не залежний. Використовуйте Обіцянку, щоб ви могли чекати результату. Він повертає тіло відповіді і не перевіряє код статусу відповіді.

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

Використання:

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',
    })
})

Для чого використовується writeметод req,write()?
Арі

@Ari, записуючий тіло запиту ... nodejs.org/api / ...
mpen

21

Ви також можете використовувати Requestify , дійсно класний і простий клієнт HTTP, який я написав для nodeJS + він підтримує кешування.

Просто виконайте наступне:

    var requestify = require('requestify');

    requestify.post('http://example.com', {
        hello: 'world'
    })
    .then(function(response) {
        // Get the response body (JSON parsed or jQuery object for XMLs)
        response.getBody();
    });

1
Це не працює для мене, дивіться проблему тут: github.com/ranm8/requestify/isissue/2
Segal-Halevi

20

Оновлення 2020:

Мені дуже подобається phin - надлегкий HTTP-клієнт Node.js

Його можна використовувати двома різними способами. Один із Обіцянками (Async / Await), а другий із традиційними стилями зворотного дзвінка.

Встановити через: npm i phin

Прямо з цього README await:

const p = require('phin')

await p({
    url: 'https://ethanent.me',
    method: 'POST',
    data: {
        hey: 'hi'
    }
})


Безпромісний стиль (зворотний виклик):

const p = require('phin').unpromisified

p('https://ethanent.me', (err, res) => {
    if (!err) console.log(res.body)
})

Станом на 2015 рік, зараз існує велика кількість різноманітних бібліотек, які можуть досягти цього за допомогою мінімального кодування. Я дуже віддаю перевагу елегантним бібліотекам з невеликою вагою для HTTP запитів, якщо вам абсолютно не потрібен контроль над HTTP-матеріалами низького рівня.

Однією з таких бібліотек є Unirest

Щоб встановити його, використовуйте npm.
$ npm install unirest

І на Hello, World!приклад, до якого всі звикли.

var unirest = require('unirest');

unirest.post('http://example.com/helloworld')
.header('Accept', 'application/json')
.send({ "Hello": "World!" })
.end(function (response) {
  console.log(response.body);
});


Додатково:
Багато людей також пропонують використовувати запит [2]

Варто зазначити, що за лаштунками Unirestвикористовує requestбібліотеку.

Unirest надає методи доступу безпосередньо до об'єкта запиту.

Приклад:

var Request = unirest.get('http://mockbin.com/request');

1
Ще одне, що я виявив, що виглядає досить добре, - це github.com/request/request, який здається трохи популярнішим, ніж unirest, принаймні станом на це написання
Lochlan

Я можу засвідчити запит. Це дуже гарна бібліотека. Я вважаю, що запит забезпечує більш низький рівень функціональності, тому доцільно використовувати його для конкретних програм. Коли я не обов'язково дбаю про речі низького рівня, я вважаю, що Unirest є адекватним.
Леві Робертс

Чому б unirest вважався легким, коли це залежить від запиту? Сам запит має 22 залежності, я не бачу, як це легка вага
raphadko

@raphadko Я впевнений, що з роками трапляється функція розриву. Не забудьте перевірити мітку часу, коли я розмістив свою відповідь;)
Леві Робертс

17
var https = require('https');


/**
 * HOW TO Make an HTTP Call - POST
 */
// do a POST request
// create the JSON object
jsonObject = JSON.stringify({
    "message" : "The web of things is approaching, let do some tests to be ready!",
    "name" : "Test message posted with node.js",
    "caption" : "Some tests with node.js",
    "link" : "http://www.youscada.com",
    "description" : "this is a description",
    "picture" : "http://youscada.com/wp-content/uploads/2012/05/logo2.png",
    "actions" : [ {
        "name" : "youSCADA",
        "link" : "http://www.youscada.com"
    } ]
});

// prepare the header
var postheaders = {
    'Content-Type' : 'application/json',
    'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};

// the post options
var optionspost = {
    host : 'graph.facebook.com',
    port : 443,
    path : '/youscada/feed?access_token=your_api_key',
    method : 'POST',
    headers : postheaders
};

console.info('Options prepared:');
console.info(optionspost);
console.info('Do the POST call');

// do the POST call
var reqPost = https.request(optionspost, function(res) {
    console.log("statusCode: ", res.statusCode);
    // uncomment it for header details
//  console.log("headers: ", res.headers);

    res.on('data', function(d) {
        console.info('POST result:\n');
        process.stdout.write(d);
        console.info('\n\nPOST completed');
    });
});

// write the json data
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
    console.error(e);
});

чи є спосіб переглянути орган поштового запиту або на запит, або на відповідь?
jacoballenwood

17

Доступні десятки бібліотек з відкритим кодом, які можна використовувати для створення HTTP POST-запиту в Node.

1. Axios (рекомендується)

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. Голка

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. Запит

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. Рідний модуль HTTPS

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();

Детальніше ознайомтеся з цією статтею .


14

Це найпростіший спосіб використання запиту: використання модуля "запит".

Команда для встановлення модуля "запит":

$ npm install request

Приклад коду:

var request = require('request')

var options = {
  method: 'post',
  body: postData, // Javascript object
  json: true, // Use,If you are sending JSON data
  url: url,
  headers: {
    // Specify headers, If any
  }
}

request(options, function (err, res, body) {
  if (err) {
    console.log('Error :', err)
    return
  }
  console.log(' Body :', body)

});

Ви також можете використовувати вбудований модуль 'http' Node.js для надсилання запиту.


1
Ця бібліотека застаріла.
Юрій Ткаченко

12

Мені подобається простота суперагенту ( https://github.com/visionmedia/superagent ). Той самий API як у вузлі, так і в браузері.

;(async function() {
  var response = await superagent.post('http://127.0.0.1:8125/', {age: 2})
  console.log(response)
})

Існує також node-fetch ( https://www.npmjs.com/package/node-fetch ), який має API, який відповідає fetchбраузерам. Однак для цього потрібне ручне кодування рядків запитів, не обробляє автоматично типи вмісту або тому будь-який інший суперагент працює.


1
І на відміну від голки, unirest та co, вона забезпечує легкість (superagent: 16k, unirest: 1M, голка: 530K)
Ларс

9

Якщо ви шукаєте HTTP-запити на основі обіцянок, axios робить свою роботу чудово.

  const axios = require('axios');

  axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})
      .then((response) => console.log(response))
      .catch((error) => console.log(error));

АБО

await axios.post('/user', {firstName: 'Fred',lastName: 'Flintstone'})

6

Для розміщення запиту на відпочинок / JSON
Ми можемо просто використовувати пакет запиту і зберегти значення, які ми повинні надсилати в змінну Json.

Спочатку встановіть пакет необхідності у вашій консолі за допомогою npm install request --save

var request = require('request');

    var options={
                'key':'28',
                'key1':'value',
                'key2':'value'
                }

    request({
             url:"http://dev.api.ean.com/ean-services/rs/hotel/v3/ping?                      
                 minorRev="+options.key+
                 "&cid="+options.key1+
                 "&apiKey="+options.key2,
             method:"POST",
             json:true},function(error,response,body){
                     console.log(body)
               }
    );

2
Ніколи не будуйте власну рядок запитів. Ви нехтуєте належним чином кодувати свої значення. Node.js має бібліотеку саме для цієї мети: nodejs.org/api/querystring.html
Бред

Ця бібліотека застаріла.
Юрій Ткаченко

4

Я знайшов відео, в якому пояснюється, як цього досягти: https://www.youtube.com/watch?v=nuw48-u3Yrg

Він використовує модуль "http" за замовчуванням разом з модулями "querystring" та "stringbuilder". Додаток бере два числа (використовуючи два текстові поля) з веб-сторінки та після надсилання повертає суму цих двох (разом із збереженням значень у текстових полях). Це найкращий приклад, який я міг знайти деінде.

var http = require("http");
var qs = require("querystring");
var StringBuilder = require("stringbuilder");

var port = 9000;

function getCalcHtml(req, resp, data) {
    var sb = new StringBuilder({ newline: "\r\n" });
    sb.appendLine("<html>");
    sb.appendLine(" <body>");
    sb.appendLine("     <form method='post'>");
    sb.appendLine("         <table>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter First No: </td>");

    if (data && data.txtFirstNo) {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td>Enter Second No: </td>");

    if (data && data.txtSecondNo) {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo);
    }
    else {
        sb.appendLine("                 <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>");
    }

    sb.appendLine("             </tr>");
    sb.appendLine("             <tr>");
    sb.appendLine("                 <td><input type='submit' value='Calculate' /></td>");
    sb.appendLine("             </tr>");

    if (data && data.txtFirstNo && data.txtSecondNo) {
        var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo);
        sb.appendLine("             <tr>");
        sb.appendLine("                 <td>Sum: {0}</td>", sum);
        sb.appendLine("             </tr>");
    }

    sb.appendLine("         </table>");
    sb.appendLine("     </form>")
    sb.appendLine(" </body>");
    sb.appendLine("</html>");
    sb.build(function (err, result) {
        resp.write(result);
        resp.end();
    });
}

function getCalcForm(req, resp, data) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    getCalcHtml(req, resp, data);
}

function getHome(req, resp) {
    resp.writeHead(200, { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href='/calc'>here</a></body></html>");
    resp.end();
}

function get404(req, resp) {
    resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href='/'>Home</a></body></html>");
    resp.end();
}

function get405(req, resp) {
    resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" });
    resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>");
    resp.end();
}

http.createServer(function (req, resp) {
    switch (req.method) {
        case "GET":
            if (req.url === "/") {
                getHome(req, resp);
            }
            else if (req.url === "/calc") {
                getCalcForm(req, resp);
            }
            else {
                get404(req, resp);
            }
            break;
        case "POST":
            if (req.url === "/calc") {
                var reqBody = '';
                req.on('data', function (data) {
                    reqBody += data;
                    if (reqBody.length > 1e7) { //10MB
                        resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' });
                        resp.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
                    }
                });
                req.on('end', function () {
                    var formData = qs.parse(reqBody);
                    getCalcForm(req, resp, formData);
                });
            }
            else {
                get404(req, resp);
            }
            break;
        default:
            get405(req, resp);
            break;
    }
}).listen(port);

4

Це моє рішення для POSTі GET.

Про Postметод:

Якщо тіло є об'єктом JSON, важливо його десеріалізувати JSON.stringifyі, можливо, встановити Content-Lenghtзаголовок відповідно:

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

перед тим, як написати його на запит:

request.write( bodyString );

Про те Getі Postметоди:

Це timeoutможе статися як socketвідключення, тому ви повинні зареєструвати його обробник на зразок:

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обробник

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

Я настійно пропоную зареєструвати обидва обробники.

Корпус відповідей урізаний, тож ви повинні стиснути шматки у dataобробника:

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

На міститиме всі тіло відповіді:endbody

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

Це безпечно, щоб обернути з try... catch theJSON.parse`, оскільки ви не можете бути впевнені, що це насправді добре відформатований json, і немає можливості бути впевненим у цьому під час виконання запиту.

Модуль: 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);

Використання:

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

4

Після великої боротьби під час створення утиліти низького рівня для обробки пошти та отримання запитів на мій проект, я вирішив розмістити свої зусилля тут. Багато в рядках прийнятої відповіді, ось фрагмент для отримання http та https POST-запитів для надсилання даних JSON.

const http = require("http")
const https = require("https")

// Request handler function
let postJSON = (options, postData, callback) => {

    // Serializing JSON
    post_data = JSON.stringify(postData)

    let port = options.port == 443 ? https : http

    // Callback function for the request
    let req = port.request(options, (res) => {
        let output = ''
        res.setEncoding('utf8')

        // Listener to receive data
        res.on('data', (chunk) => {
            output += chunk
        });

        // Listener for intializing callback after receiving complete response
        res.on('end', () => {
            let obj = JSON.parse(output)
            callback(res.statusCode, obj)
        });
    });

   // Handle any errors occurred while making request
    req.on('error', (err) => {
        //res.send('error: ' + err.message)
    });

    // Request is made here, with data as string or buffer
    req.write(post_data)
    // Ending the request
    req.end()
};

let callPost = () => {

    let data = {
        'name': 'Jon',
        'message': 'hello, world'
    }

    let options = {
        host: 'domain.name',       // Your domain name
        port: 443,                 // 443 for https and 80 for http
        path: '/path/to/resource', // Path for the request
        method: 'POST',            
        headers: {
            'Content-Type': 'application/json',
            'Content-Length': Buffer.byteLength(data)
        }
    }

    postJSON(options, data, (statusCode, result) => {
        // Handle response
        // Process the received data
    });

}

2
Ви ніколи не використовуєте серіалізовані post_data? чи записує як об'єкт js перетворення в буфер за замовчуванням?
ThatBrianDude

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

Або ви можете використовувати цю бібліотеку:

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

requestбібліотека застаріла.
Юрій Ткаченко

3

Axios - це HTTP-клієнт, який обіцяє, для браузера та Node.js. Axios дозволяє легко надсилати асинхронні запити HTTP до кінцевих точок REST та виконувати операції з CRUD. Її можна використовувати в простому JavaScript або з такою бібліотекою, як Vue або React.

const axios = require('axios');

        var dataToPost = {
          email: "your email",
          password: "your password"
        };

        let axiosConfiguration = {
          headers: {
              'Content-Type': 'application/json;charset=UTF-8',
              "Access-Control-Allow-Origin": "*",
          }
        };

        axios.post('endpoint or url', dataToPost, axiosConfiguration)
        .then((res) => {
          console.log("Response: ", res);
        })
        .catch((err) => {
          console.log("error: ", err);
        })

2

Опублікування іншого прикладу axios запиту axios.post, який використовує додаткові параметри конфігурації та спеціальні заголовки.

var postData = {
  email: "test@test.com",
  password: "password"
};

let axiosConfig = {
  headers: {
      'Content-Type': 'application/json;charset=UTF-8',
      "Access-Control-Allow-Origin": "*",
  }
};

axios.post('http://<host>:<port>/<path>', postData, axiosConfig)
.then((res) => {
  console.log("RESPONSE RECEIVED: ", res);
})
.catch((err) => {
  console.log("AXIOS ERROR: ", err);
})


0

Використовуючи залежність від запиту .

Просте рішення:

 import request from 'request'
 var data = {
        "host":"127.1.1.1",
        "port":9008
    }

request.post( baseUrl + '/peers/connect',
        {
            json: data,  // your payload data placed here
            headers: {
                'X-Api-Key': 'dajzmj6gfuzmbfnhamsbuxivc', // if authentication needed
                'Content-Type': 'application/json' 
            }
        }, function (error, response, body) {
            if (error) {
                callback(error, null)
            } else {
                callback(error, response.body)
            }
        });

3
звідки береться request?
CodyBugstein

Ця бібліотека застаріла.
Юрій Ткаченко

0

Request-PromiseЗабезпечує відповідь на основі обіцянок. http відповідні коди, окрім 2xx, спричинить відхилення обіцянки. Це можна перезаписати, встановивши options.simple = false

var options = {
  method: 'POST',
  uri: 'http://api.posttestserver.com/post',
  body: {
  some: 'payload'
 },
  json: true // Automatically stringifies the body to JSON
};

rp(options)
.then(function (parsedBody) {
    // POST succeeded...
})
.catch(function (err) {
    // POST failed...
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.