Node.js Express中的HTTP GET请求
如何从node / express内部发出HTTP请求? 我需要连接到另一个服务。 我希望这个调用是asynchronous的,并且callback包含远程服务器响应。
这里是我的一个样本的代码。 它是asynchronous的并返回一个JSON对象。 它可以做任何获取请求。 请注意,有更多的最佳方式(只是一个示例),例如,而不是连接你放入数组中的块,并join等等。希望你能从正确的方向开始:
var http = require("http"); var https = require("https"); /** * getJSON: REST get request returning JSON object(s) * @param options: http options object * @param callback: callback to pass the results JSON object(s) back */ exports.getJSON = function(options, onResult) { console.log("rest::getJSON"); var port = options.port == 443 ? https : http; var req = port.request(options, function(res) { var output = ''; console.log(options.host + ':' + res.statusCode); res.setEncoding('utf8'); res.on('data', function (chunk) { output += chunk; }); res.on('end', function() { var obj = JSON.parse(output); onResult(res.statusCode, obj); }); }); req.on('error', function(err) { //res.send('error: ' + err.message); }); req.end(); };
这是通过创build一个选项对象调用:
var options = { host: 'somesite.com', port: 443, path: '/some/path', method: 'GET', headers: { 'Content-Type': 'application/json' } };
并提供callback函数。
例如,在服务中,我需要上面的其他模块,然后执行此操作。
rest.getJSON(options, function(statusCode, result) { // I could work with the result html/json here. I could also just return it console.log("onResult: (" + statusCode + ")" + JSON.stringify(result)); res.statusCode = statusCode; res.send(result); });
更新:
如果您正在寻找asynchronous等待(线性无callback),承诺,编译时间支持和智能感知,我们创build一个轻量级的http和rest客户端适合该法案:
尝试在node.js中使用简单的http.get(options, callback)
函数 :
var http = require('http'); var options = { host: 'www.google.com', path: '/index.html' }; var req = http.get(options, function(res) { console.log('STATUS: ' + res.statusCode); console.log('HEADERS: ' + JSON.stringify(res.headers)); // Buffer the body entirely for processing as a whole. var bodyChunks = []; res.on('data', function(chunk) { // You can process streamed parts here... bodyChunks.push(chunk); }).on('end', function() { var body = Buffer.concat(bodyChunks); console.log('BODY: ' + body); // ...and/or process the entire body here. }) }); req.on('error', function(e) { console.log('ERROR: ' + e.message); });
还有一个通用的http.request(options, callback)
函数可以让你指定请求方法和其他的请求细节。
请求和Superagent是相当不错的图书馆使用。
使用request
:
var request=require('request'); request.get('https://someplace',options,function(err,res,body){ if(err) //TODO: handle err if(res.statusCode !== 200 ) //etc //TODO Do something with response });
你也可以使用Requestify ,一个非常酷,非常简单的HTTP客户端,我为nodeJS +写的它支持caching。
只需执行以下GET方法请求:
var requestify = require('requestify'); requestify.get('http://example.com/api/resource') .then(function(response) { // Get the response body (JSON parsed or jQuery object for XMLs) response.getBody(); } );
Unirest是我从Node接收HTTP请求的最好的库。 它的目标是成为一个多平台框架,所以如果您需要在Ruby,PHP,Java,Python,Objective C,.Net或Windows 8上使用HTTP客户端,那么了解它如何在Node上工作将会很好地为您服务。 据我所知,不公平的库大部分都支持现有的HTTP客户端(例如Java,Apache HTTP客户端,Node, Mikeal的请求库 ) – Unirest只是把一个更好的API放在最前面。
以下是Node.js的几个代码示例:
var unirest = require('unirest') // GET a resource unirest.get('http://httpbin.org/get') .query({'foo': 'bar'}) .query({'stack': 'overflow'}) .end(function(res) { if (res.error) { console.log('GET error', res.error) } else { console.log('GET response', res.body) } }) // POST a form with an attached file unirest.post('http://httpbin.org/post') .field('foo', 'bar') .field('stack', 'overflow') .attach('myfile', 'examples.js') .end(function(res) { if (res.error) { console.log('POST error', res.error) } else { console.log('POST response', res.body) } })
您可以直接跳到这里的Node文档
看看切丝 。 这是一个由spire.io创build和维护的节点HTTP客户端,用于处理redirect,会话和JSON响应。 与其他API交互是非常好的。 看到这个博客文章的更多细节。
查看httpreq :这是我创build的节点库,因为我感到沮丧,没有简单的http GET或POST模块;-)
这个版本是基于最初由bryanmac函数提出的,它使用承诺,更好的error handling,并且在ES6中被重写。
let http = require("http"), https = require("https"); /** * getJSON: REST get request returning JSON object(s) * @param options: http options object */ exports.getJSON = function(options) { console.log('rest::getJSON'); let reqHandler = +options.port === 443 ? https : http; return new Promise((resolve, reject) => { let req = reqHandler.request(options, (res) => { let output = ''; console.log('rest::', options.host + ':' + res.statusCode); res.setEncoding('utf8'); res.on('data', function (chunk) { output += chunk; }); res.on('end', () => { try { let obj = JSON.parse(output); // console.log('rest::', obj); resolve({ statusCode: res.statusCode, data: obj }); } catch(err) { console.error('rest::end', err); reject(err); } }); }); req.on('error', (err) => { console.error('rest::request', err); reject(err); }); req.end(); }); };
因此,您不必传递callback函数,而是getJSON()返回一个承诺。 在以下示例中,该函数在ExpressJS路由处理程序中使用
router.get('/:id', (req, res, next) => { rest.getJSON({ host: host, path: `/posts/${req.params.id}`, method: 'GET' }).then(({status, data}) => { res.json(data); }, (error) => { next(error); }); });
错误时,它将错误委托给服务器error handling中间件。
如果您只需要简单的获取请求,并且不需要任何其他HTTP方法的支持,请查看: simple-get :
var get = require('simple-get'); get('http://example.com', function (err, res) { if (err) throw err; console.log(res.statusCode); // 200 res.pipe(process.stdout); // `res` is a stream });
使用reqclient :不是为request
或许多其他库的脚本目的而devise的。 Reqclient允许在构造函数中指定许多有用的configuration,当你需要一次又一次地重复使用同一个configuration时:base URL,headers,auth选项,日志选项,caching等。还有一些有用的function,比如查询和URLparsing,自动查询编码和JSONparsing等
使用库的最好方法是创build一个模块来导出指向API的对象和必要的连接configuration:
模块client.js
:
let RequestClient = require("reqclient").RequestClient let client = new RequestClient({ baseUrl: "https://myapp.com/api/v1", cache: true, auth: {user: "admin", pass: "secret"} }) module.exports = client
而在需要使用API的控制器中,像这样使用:
let client = require('client') //let router = ... router.get('/dashboard', (req, res) => { // Simple GET with Promise handling to https://myapp.com/api/v1/reports/clients client.get("reports/clients") .then(response => { console.log("Report for client", response.userId) // REST responses are parsed as JSON objects res.render('clients/dashboard', {title: 'Customer Report', report: response}) }) .catch(err => { console.error("Ups!", err) res.status(400).render('error', {error: err}) }) }) router.get('/orders', (req, res, next) => { // GET with query (https://myapp.com/api/v1/orders?state=open&limit=10) client.get({"uri": "orders", "query": {"state": "open", "limit": 10}}) .then(orders => { res.render('clients/orders', {title: 'Customer Orders', orders: orders}) }) .catch(err => someErrorHandler(req, res, next)) }) router.delete('/orders', (req, res, next) => { // DELETE with params (https://myapp.com/api/v1/orders/1234/A987) client.delete({ "uri": "orders/{client}/{id}", "params": {"client": "A987", "id": 1234} }) .then(resp => res.status(204)) .catch(err => someErrorHandler(req, res, next)) })
reqclient
支持许多function,但它有一些不被其他库支持: OAuth2集成和logging器与cURL语法集成,并始终返回本机Promise对象。
如果只是redirect,您可以使用简单的redirect脚本,
res.writeHead(301, { Location: "http" + (req.socket.encrypted ? "s" : "") + "://" + req.headers.host + loc, });
那么, res.send();
其中variables'loc'可以是任何格式化的(GET)查询string
很好地将授权参数直接发送到客户端主机。