Node.js系列 :5個方法產生非同步Http 請求

jessweb3
·
·
IPFS
·
作為我的第一篇 Post,就從 Node.js 開始吧!

相信各位在寫程式時都避不開一個問題:大量的 Http Request!在存取任何型態的遠端資源 ( API、網頁、File…… )時都會用到。而到底有哪些模組在Node.js 中可以用來達成目標呢 ?我們往下看吧!

以下分享為了簡潔以及易於理解,本文皆使用 GET 請求來說明。

你將學到

  • 如何用不同的 modules 發出Http請求
  • 每一個 module 的優缺點

閱讀需求

  • 建議對 Javascript 和 ES6 語法有基本的了解
  • 實際在 Local 安裝 Node.js 7.6.0以上

建置專案

創建一個空的資料夾並且用 npm 初始化它

mkdir test && cd $_
npm init -y

Node.js 中有兩種簡明的模式可以產生 Http 請求:

  • 經典的 callback pattern
  • (用多了會導致著名的 callback hell,非常難維護!)
  • 支援 Promises,代表可以使用 async/await
  • (Promises 觀念非常重要,不懂的建議先從下方連結理解喔)

https://developers.google.com/web/fundamentals/primers/promises?hl=zh-tw

我們就從 callback 開始吧!

1. http.get 和 https.get

第一個選擇就是 Node.js 內建原生的 http.get 和 https.get,如果只是要做非常單純的 GET 請求,可以用他們就好。

優點:

  • 原生 API ,不用額外安裝 module
  • 回應是串流所以需要較多的手工處理
  • (優點也是缺點,但我覺得可以多學點也是個優點?)

缺點:

  • 會多寫很多 code,之後可能很難維護
  • 同第二個優點
  • 沒有支援 Promises

範例 http-native.js

const https = require("https");
const url = "https://api.jasontechlab.com/posts/1";
https.get(url, res => {
res.setEncoding("utf8");
  let body = "";
  
  //接收資料
  res.on("data", data => {
    body += data;
  });
//接收完畢
  res.on("end", () => {
    body = JSON.parse(body);
    console.log(body);
  });
});

接下來執行:

node http-native.js

結果:

{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

http.get 中第一個參數是網址 url ,第二個參數是一個 callback res。

res是一個 http.ClientRequest 物件,這意味著你如果要對 response body 進行操作,則必須聽取一些事件,請看範例中res.on() 的部分,在範例中我只是簡單的 console.log 出 API 回傳的資料,實務上應該會有更複雜的操作或是將資料傳入一個 callback function

function makeResponseHandler (callback) {
    return function (response) {
        //在這處理 data, node.js native wahy
        callback(null, result);
    }
};
return {
    apiGet: function(url, callback) {
        http.get(url, makeResponseHandler(callback));
    }
}

小結:

callback模式還有一個 request module ,但是在今年二月已經被廢棄了,有興趣的可以去官網看看:

https://www.npmjs.com/package/request

用原生的方法雖然會多寫很多 code,但是你因為被迫於處理原生的 events,

會去多鑽一些 Node.js的底層,我覺得這是好事,推薦初學者使用!

接下來要學的可以用一句話代表:I Promise I’ll be async !

2. node-fetch

node-fetch 是 Fetch API 在 Node.js 中的實作,基本上跟 window.fetch 相同,所以基本上使用起來也是非常直覺。

優點:

  • 支援 Promises
  • 使用上接近 window.fetch
  • 依賴很少

缺點:

  • 不支持同步請求
  • 只會對網路報錯,對 400, 500 等都當作是成功的請求,需要封裝處理
  • 默認不會带 cookie,需要添加額外配置
  • 不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實現的超時控制不能阻止請求過程繼續在後台執行,造成了流量浪費
  • 沒有辦法原生的監測請求進度

安裝:

npm i node-fetch --save

範例 node-fetch.js

const fetch = require("node-fetch");
const url = "https://jsonplaceholder.typicode.com/posts/1";

const getData = async url => {
  try {
    const response = await fetch(url);
    const json = await response.json();
    console.log(json);
  } catch (error) {
    console.log(error);
  }
};

getData(url);

執行:

node node-fetch.js

小結:

我本身不是很愛用 node-fetch,因為我不愛 Fetch API所以也不愛它XD,想到處理回傳時要寫 json() 和兩次 then() 就覺得很煩,不過每人都有所愛,選擇自己適合的最重要。


3. r2

request module 的作者在2017年開發的,也算是 Fetch API的另一個實作,這意味者:r2 底層是 node-fetch……

優缺點同 node-fetch

安裝:

npm i r2

範例 r2.js

const r2 = require("r2");
const url = "https://jsonplaceholder.typicode.com/posts/1";

const getData = async url => {
  try {
    const response = await r2(url).json;
    console.log(response);
  } catch (error) {
    console.log(error);
  }
};

getData(url);

執行:

node r2.js

小結:

我承認我沒有花時間去研究它(因為本來就對 node-fetch有排斥了),但有興趣的可以去看看它新增的特性以及改良的地方,搞不好你會喜歡。


4. axios

axios 是現在超流行的 module,也是我最常使用的。它天生就支援了 Promises所以 code 寫起來非常簡潔。

axios 被拿來使用在前後端都可以,而且可以針對 response 自動轉換,不需要像 node-fetch 一樣寫 json() 啦!

優點:

  • 支援Promises
  • 使用容易簡明
  • 只有兩個依賴

缺點:

  • ?? (有知道的可以跟我說)

安裝:

npm i axios

範例 axios-module.js

const axios = require("axios");
const url = "https://jsonplaceholder.typicode.com/posts/1";

const getData = async url => {
  try {
    const response = await axios.get(url);
    const data = response.data;
    console.log(data);
  } catch (error) {
    console.log(error);
  }
};

getData(url);

執行:

node axios-module.js

小結:

目前我找不太到 axios 缺點,他是如此的易用跟方便配置,或許等以後 Fetch 技術成熟到可以取代 Ajax 時的那一天才有可能找到吧。

總結:

通過以上簡易的比較,大家都可以試試,目前還是最推薦使用 axios。我最近有關注一個後起之秀 bent,它用起來比 axios 更為簡潔,大家有興趣可以去嘗試一下:

https://github.com/mikeal/bent

CC BY-NC-ND 2.0

Like my work? Don't forget to support and clap, let me know that you are with me on the road of creation. Keep this enthusiasm together!

jessweb3youtube: https://www.youtube.com/channel/UCgH6CL6wswgYuaKIVXa5iOw linkedin: https://www.linkedin.com/in/tengwen/ 熱愛分享技術、讀書、享受生活
  • Author
  • More

書摘 | 讀懂一本書

多執行緒系列:Blocking Queue 概念與實作

區塊鏈系列 - 以太坊工作原理 (上)