如何在node.js中进行HTTP POST请求?

我如何能使出站HTTP POST请求,与数据,在node.js?

1436071 次浏览

下面是一个使用node.js向谷歌编译器API发出POST请求的例子:

// We need this to build our post stringvar querystring = require('querystring');var http = require('http');var fs = require('fs');
function PostCode(codestring) {// Build the post string from an objectvar 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 tovar 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 requestvar post_req = http.request(post_options, function(res) {res.setEncoding('utf8');res.on('data', function (chunk) {console.log('Response: ' + chunk);});});
// post the datapost_req.write(post_data);post_req.end();
}
// This is an async file readfs.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 itif(data) {PostCode(data);}else {console.log("No data to post");process.exit(-1);}});

我已经更新了代码,以展示如何从文件中发布数据,而不是硬编码的字符串。它使用async# 0命令来实现这一点,在成功读取后发布实际代码。如果出现错误,则抛出错误,如果没有数据,则进程退出,并显示一个负值以指示失败。

request现在已弃用。第一,你要使用替代方案

无特定顺序且极不完整的:

统计比较# 0 < / p >

最初的回答:

如果使用请求库,这将变得容易得多。

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签名(twitter等),可以做多部分的表单(例如上传文件)和流。

安装请求使用命令npm install request

我喜欢超级代理的简单性(https://github.com/visionmedia/superagent)。节点和浏览器上的API相同。

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

还有节点获取(https://www.npmjs.com/package/node-fetch),它有一个与浏览器中的fetch匹配的API——但是这需要手动查询字符串编码,不能自动处理内容类型,或者超级代理所做的任何其他工作。

我使用Restler用于生产目的。它们都比本地httprequest强大得多。可以使用基本的身份验证,特殊的头条目或甚至上传/下载文件进行请求

至于post/get操作,它们也比使用httprequest的原始ajax调用简单得多。

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

你也可以使用Requestify,这是我为nodeJS +编写的一个非常酷而简单的HTTP客户端,它支持缓存。

只需要做以下几点:

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

您可以使用请求库。# 0

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

截至2020年2月,request已经成为# 1

< p > # 0 < br >我们可以简单地使用请求包,并保存我们必须在Json变量中发送的值

首先在控制台中安装require包NPM安装请求——保存

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

2020年更新:

我真的很享受从0到1

它有两种不同的用法。一个是promise (Async/Await),另一个是传统的回调样式。

安装路径:npm i phin

直接从它的README await:

const p = require('phin')
await p({url: 'https://ethanent.me',method: 'POST',data: {hey: 'hi'}})
< p > < br >未承诺(回调)样式:

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

2015开始,现在有很多不同的库可以用最少的代码实现这一点。我更喜欢优雅的轻量级HTTP请求库,除非你绝对需要控制低级HTTP的东西。

Unirest就是这样一个库

要安装它,请使用npm。< br ># 0 < / p >

然后是大家都熟悉的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);});
< p > 0 < br > < br > #很多人也建议使用请求 [2]

值得注意的是,Unirest在幕后使用的是request库。

Unirest提供了直接访问请求对象的方法。

# 0 < br >

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

我找到了一个视频,它解释了如何实现这一点: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) { //10MBresp.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);

这是我用来发出请求的最简单的方式:使用'request'模块。

命令安装'request'模块:

$ npm install request

示例代码:

var request = require('request')
var options = {method: 'post',body: postData, // Javascript objectjson: true, // Use,If you are sending JSON dataurl: url,headers: {// Specify headers, If any}}
request(options, function (err, res, body) {if (err) {console.log('Error :', err)return}console.log(' Body :', body)
});

你也可以使用Node.js内置的“http”模块来发出请求。

这是0和1的解。

关于Post方法:

如果body是一个JSON对象,那么使用JSON.stringify反序列化它并相应地设置Content-Lenght头是很重要的:

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

在写入请求之前:

request.write( bodyString );

关于GetPost方法:

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

end处,body将包含整个响应体:

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

使用try…catchtheJSON进行包装是安全的。解析,因为你不能确定它实际上是一个格式良好的json,也没有办法在你做请求的时候确定它。

模块:# 0

/*** 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 sslthis.http = require('https');} else { // go unsafe, debug only pleasethis.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 ! 80options['port']=this.port;}if(self.debug) {console.log( "SimpleAPI.Get", headers, params, options );}var request=this.http.get(options, function(response) {
if(self.debug) { // debugconsole.log( JSON.stringify(response.headers) );}
// Continuously update stream with datavar 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 jsonif(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 garbageconsole.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 ! 80options['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) { // debugconsole.log( JSON.stringify(response.headers) );}
// Continuously update stream with datavar 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 jsonif(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 garbageconsole.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:truevar 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) { // successconsole.log( response );}, function(error) { // errorconsole.log( error.toString() );}, function(error) { // timeoutconsole.log( new Error('timeout error') );});
var https = require('https');

/*** HOW TO Make an HTTP Call - POST*/// do a POST request// create the JSON objectjsonObject = 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 headervar postheaders = {'Content-Type' : 'application/json','Content-Length' : Buffer.byteLength(jsonObject, 'utf8')};
// the post optionsvar 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 callvar 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 datareqPost.write(jsonObject);reqPost.end();reqPost.on('error', function(e) {console.error(e);});

在为我的项目创建了一个低级实用程序来处理帖子和获取请求之后,我决定在这里发布我的努力。这里有一个关于发送JSON数据的http和https POST请求的代码片段。

const http = require("http")const https = require("https")
// Request handler functionlet postJSON = (options, postData, callback) => {
// Serializing JSONpost_data = JSON.stringify(postData)
let port = options.port == 443 ? https : http
// Callback function for the requestlet req = port.request(options, (res) => {let output = ''res.setEncoding('utf8')
// Listener to receive datares.on('data', (chunk) => {output += chunk});
// Listener for intializing callback after receiving complete responseres.on('end', () => {let obj = JSON.parse(output)callback(res.statusCode, obj)});});
// Handle any errors occurred while making requestreq.on('error', (err) => {//res.send('error: ' + err.message)});
// Request is made here, with data as string or bufferreq.write(post_data)// Ending the requestreq.end()};
let callPost = () => {
let data = {'name': 'Jon','message': 'hello, world'}
let options = {host: 'domain.name',       // Your domain nameport: 443,                 // 443 for https and 80 for httppath: '/path/to/resource', // Path for the requestmethod: 'POST',headers: {'Content-Type': 'application/json','Content-Length': Buffer.byteLength(data)}}
postJSON(options, data, (statusCode, result) => {// Handle response// Process the received data});
}

如果您正在寻找基于承诺的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'})

发布另一个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);})

通过使用请求依赖。

简单的解决方法:

 import request from 'request'var data = {"host":"127.1.1.1","port":9008}
request.post( baseUrl + '/peers/connect',{json: data,  // your payload data placed hereheaders: {'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)}});

简单且无依赖。使用承诺,让你可以等待结果。它返回响应体,不检查响应状态代码。

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 resBody = Buffer.concat(chunks);switch(res.headers['content-type']) {case 'application/json':resBody = JSON.parse(resBody);break;}resolve(resBody)})})req.on('error',reject);if(body) {req.write(body);}req.end();})}

用法:

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)})
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-Promise提供基于承诺的响应。非2xx的HTTP响应代码将导致承诺被拒绝。这可以通过设置选项来覆盖。简单= 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...});

有许多可用的开源库,您可以使用它们在Node中发出HTTP POST请求。

1. # 0(推荐)

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. # 0

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.# 0

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. # 0

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

有关详细信息,请查看文章

# 0

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

如果您需要XML请求,我将与axios库共享我的代码。

const {default: axios} = require('axios');
let xmlString = '<XML>...</XML>';
axios.post('yourURL', xmlString).then((res) => {console.log("Status: ", res.status);console.log("Body: ", res.data);}).catch((err) => {console.error("Error: ", err);});

在Node.js 18

node-fetch包axios请求...说再见吧,现在获取 API默认在全局作用域中可用了。

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

我们可以像在浏览器中那样发出请求。

For More Information