深刻解析Node.js中5種發起HTTP請求的方法javascript
翻譯:瘋狂的技術宅 英文標題:5 Ways to Make HTTP Requests in Node.js 原文連接:www.twilio.com/blog/2017/0…html
建立HTTP請求使現代編程語言的核心功能之一,也是不少程序員在接觸到新的開發環境時最早遇到的技術之一。在Node.js中有至關多的解決方案,其中有語言內置功能,也有開源社區貢獻的開發庫。下面我們來看一下比較流行的幾種方式。java
在本文的案例中,咱們將使用NASA提供的「每日太空照片API」做爲交互用的JSON API, 由於太空是有史以來最酷的東西。node
在開始以前,請先在本身的計算機上安裝最新版的node.js和npm。python
首先是標準庫中默認的HTTP
模塊。這個模塊無需安裝依賴外部便可使用,作到了真正的即插即用。缺點是與其餘解決方案相比,用起來不是那麼友好。ios
下面的代碼將向NASA的API發送一個GET
請求,並輸出當天的天文照片的URL,以及它的註解:git
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
模塊提供的大多數功能是至關有限的。你須要以區塊爲單位接收響應數據,而不是隻提供一個回調函數,以便在收到全部數據後就當即執行。若是它是JSON格式你還須要進行手動解析。儘管工做量不大,可是它仍然會帶來一些沒必要要的操做。程序員
另外一個麻煩是,HTTP
和HTTPS
協議分屬兩個模塊,所以若是咱們使用的API是經過HTTPS
協議進行通訊,則須要HTTPS
模塊。github
若是你不想向代碼庫中添加太多的依賴項或但願使用其底層的功能, 那麼可能須要花費更多的精力來獲取所需的數據, 儘管如此,可是它仍然是一個很好的工具。npm
Request是一個簡化的http客戶端,它和Python的request庫很像。這個庫比默認的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是一個很好的選擇。若是你想使用Promises,也能夠簽出request-promise庫。
Axios是一個基於promise的HTTP客戶端,能夠用於瀏覽器和Node.js。在處理須要更復雜的事件鏈的代碼時,使用Promises具備很大的優點。 編寫異步代碼可能會使人困惑,而Promises是這個問題的幾種解決方案之一。 它們甚至被用在其它語言中,好比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()
完成的,如今咱們都在使用 promises。
你甚至能夠經過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);
});
複製代碼
異步代碼很容易地變得十分複雜而且不容易處理, 和 it 解決這個問題的方式可能會讓你的生活更容易從長遠來看。Axios很輕鬆的解決了這個問題,從長遠看來可使你的開發工做變得輕鬆。
與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是另一個選擇。它也可用於Twilio Functions。
再來一遍,實用npm安裝Got:
npm install got@7.1.0
複製代碼
和Axios同樣,Got也能同Promises一塊兒很好的工做。下面的代碼作的事情和前面的例子同樣:
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 。