本文详细解析在Node.js中发起HTTP请求的五种主流方式。从内置的http/https模块到轻量级的Got,涵盖Request、Axios、SuperAgent等流行库。通过NASA API示例,对比各方案在代码简洁性、错误处理、Promise支持及并发请求等方面的差异,帮助开发者根据项目需求选择最佳方案。
Node.js HTTP请求概述
发起HTTP请求是现代编程语言的核心能力之一,也是开发者接触新环境时最常遇到的技术点。Node.js提供了丰富的解决方案,既包含语言内置功能,也有大量开源社区贡献的第三方库。本文将介绍几种目前较为流行的实现方式。
在开始实践之前,请确保本地计算机已安装最新版本的Node.js和npm工具。
HTTP - 标准库
使用标准HTTP模块
首先介绍的是Node.js标准库中默认的HTTP模块。该模块无需安装任何外部依赖即可直接使用,具备即插即用的特性。然而,与其他第三方解决方案相比,其API设计不够友好,使用体验相对基础。
以下代码演示了如何向NASA API发送GET请求,并输出当天的天文照片URL及其注解说明:
const https = require('https');
https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
HTTP和HTTPS模块提供的功能相对有限。开发者需要以数据块(chunk)的形式接收响应数据,而非通过单一回调函数在数据接收完毕后立即执行。此外,若响应数据为JSON格式,还需手动进行解析。尽管操作并不复杂,但这仍引入了不必要的额外工作量。
另一个不便之处在于,HTTP和HTTPS协议分别归属于两个不同的模块。因此,如果调用的API基于HTTPS协议通信,必须引入并使用HTTPS模块。
如果希望避免向代码库中引入过多依赖,或者需要利用底层功能,尽管获取数据可能需要投入更多精力,但该模块依然是一个可靠的基础工具。
使用Request库
Request
Request是一个简化的HTTP客户端库,其设计理念与Python的requests库相似。相较于默认的http模块,该库更易用,多年来一直是开源社区开发的首选工具之一。
自Node.js普及以来,该库便备受青睐,有助于快速完成开发任务。与内置http模块不同,使用此库必须通过npm进行安装。
在终端中进入代码存放目录,执行以下安装命令:
npm install request@2.81.0
可以看到,无需编写大量代码即可实现前述功能:
const request = require('request');
request('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
console.log(body.url);
console.log(body.explanation);
});
若希望以常规方式处理HTTP请求,Request是一个极佳的选择。若需使用Promise风格,可进一步查阅request-promise库。
使用Axios库
Axios
Axios是一个基于Promise的HTTP客户端,适用于浏览器和Node.js环境。在处理涉及复杂事件链的代码时,使用Promise具有显著优势。异步代码编写往往令人困惑,而Promise是解决该问题的方案之一,甚至被Swift等其他语言所采用。
通过npm安装Axios,在终端输入以下命令:
npm install axios@0.16.2
以下代码实现了相同的功能,获取URL并解释当天的天文学图片:
const axios = require('axios');
axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY')
.then(response => {
console.log(response.data.url);
console.log(response.data.explanation);
})
.catch(error => {
console.log(error);
});
默认情况下,Axios会自动解析JSON响应,十分便捷。同时可以看到,错误处理通过.catch()方法完成,这符合当前使用Promise的编程习惯。
你甚至可以通过axios.all发起多个并发请求。例如,若想一次性获取两天的天文图片,可以按以下方式操作:
var axios = require('axios');
axios.all([
axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-03'),
axios.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&date=2017-08-02')
]).then(axios.spread((response1, response2) => {
console.log(response1.data.url);
console.log(response2.data.url);
})).catch(error => {
console.log(error);
});
异步代码容易变得复杂且难以维护,而Promise的引入方式能在长远来看简化开发流程。Axios轻松解决了这一问题,有助于使长期的开发工作更加轻松。
使用SuperAgent库
SuperAgent
与Axios类似,SuperAgent是另一个流行库,主要用于浏览器中的Ajax请求,同时也适用于Node.js。使用以下命令安装SuperAgent:
npm install superagent@3.5.2
SuperAgent最显著的特点是支持链式调用。你可以将其他函数链接到如query()这样的请求方法上,并添加参数。在前面的例子中,我们是手动添加参数的。请注意SuperAgent是如何提供这种链式功能的:
const superagent = require('superagent');
superagent.get('https://api.nasa.gov/planetary/apod')
.query({ api_key: 'DEMO_KEY', date: '2017-08-02' })
.end((err, res) => {
if (err) { return console.log(err); }
console.log(res.body.url);
console.log(res.body.explanation);
});
与Axios一样,你无需手动解析JSON响应,这一特性非常实用。
使用Got库
Got
若希望使用更轻量级的库,Got是另一个不错的选择。它同样适用于Twilio Functions等场景。
再次通过npm安装Got:
npm install got@7.1.0
与Axios一样,Got也能与Promise良好配合。以下代码执行的操作与前述示例相同:
const got = require('got');
got('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY', { json: true }).then(response => {
console.log(response.body.url);
console.log(response.body.explanation);
}).catch(error => {
console.log(error.response.body);
});
若需要一个不像Request那样臃肿的轻量级库,使用Got是理想选择。
总结与扩展
最后的想法
以上列举的并非全部解决方案,但通过上述内容,你已了解Node.js中一些流行HTTP库的基本工作原理。此外还有诸如node-fetch等库,将浏览器的fetch功能移植到了后端。在其他语言如Python和Ruby中,也有类似的库用于解决此类问题。
5 Ways to Make HTTP Requests in Node.js 原文链接:https://www.twilio.com/blog/2017/08/http-requests-in-node-js.html
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。