自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

在 Node.js 中發(fā)出 HTTP 請求的五種方法

開發(fā) 前端
axios比superagent的功能列表很長,盡管 node-fetch 看起來很有前途并且安裝大小很小,但我不確定該 API 是否足夠用戶友好——至少對我來說是這樣。 您可能會注意到我的討論

原文來源:https://blog.logrocket.com/5-ways-make-http-requests-node-js/

原文作者:Geshan Manandhar

譯者:一川

在 Node.js 中發(fā)出 HTTP 請求的方法有多種??梢酝ㄟ^使用 Node.js 提供的標準內置 HTTP/HTTPS 模塊、利用 Node 環(huán)境中包含的 Fetch API 或選擇第三方 npm 包來簡化流程來實現(xiàn)此目的。

在本文中,將探索本機 HTTPS 模塊和 Fetch API,并研究流行的 npm 包,例如 Axios、Got、superagent 和 node-fetch,以促進高效地發(fā)出 HTTP 請求。

將使用每個 HTTP 客戶端向 JSONPlaceholder API 發(fā)出 GET 請求。它將向我們發(fā)送 10 個用戶的數(shù)據(jù)。將在控制臺上記錄每個用戶名和 ID。

Let’s get started!

標準 Node.js HTTP(S) 模塊

Node.js 帶有內置的 HTTP 和 HTTPS 模塊。在下面的示例中,使用 HTTPS 模塊對占位符 API 執(zhí)行 GET 請求:

const https = require('https');

https.get('https://jsonplaceholder.typicode.com/users', res => {
  let data = [];
  const headerDate = res.headers && res.headers.date ? res.headers.date : 'no response date';
  console.log('Status Code:', res.statusCode);
  console.log('Date in Response header:', headerDate);

  res.on('data', chunk => {
    data.push(chunk);
  });

  res.on('end', () => {
    console.log('Response ended: ');
    const users = JSON.parse(Buffer.concat(data).toString());

    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  });
}).on('error', err => {
  console.log('Error: ', err.message);
});

讓我們看一下代碼,需要使用nodejs內置的 https 模塊,該模塊在任何標準 Node.js 安裝中都可用。無需 package.json 文件或 npm install 即可開始使用它。

接下來,將 data 初始化為空數(shù)組,并記錄響應標頭中的狀態(tài)代碼和日期。每當獲得一塊數(shù)據(jù)時,就把它推入 data 數(shù)組中。收到所有響應后,連接數(shù)據(jù)數(shù)組,將其轉換為字符串,并解析 JSON 以獲取用戶列表。循環(huán)訪問用戶并將用戶 ID 和名稱記錄到控制臺。

這里需要注意一件事:如果請求出現(xiàn)錯誤,錯誤消息將記錄在控制臺上。上述代碼可作為拉取請求使用。

您可以使用 node native-https.js 命令執(zhí)行上面的代碼,前提是您將文件命名為 native-https.js 。它應該顯示如下輸出:

圖片圖片

可以使用相同的方法來運行本文中的所有其他示例;他們將顯示類似的輸出。打印狀態(tài)代碼、響應標頭中的日期以及響應正文中的用戶 ID 和名稱。

內置Fetch API

Node.js 在 v16.15.0 中提供了 Fetch API 的瀏覽器兼容實現(xiàn)的實驗版本,并在 Node v21 中變得穩(wěn)定。

Fetch 在環(huán)境中本身可用,無需導入或單獨需要。這個內置 API 具有多種優(yōu)勢:無需持續(xù)維護,最大限度地減少安全問題,并且不會影響捆綁包大小或通常與第三方軟件包相關的許可問題。

您可以將 Fetch API 與 async/await 或 Promise 鏈結合使用:

(async () => {
  try {
    const res = await fetch('https://jsonplaceholder.typicode.com/users');
    const headerDate = res.headers && res.headers.get('date') ? res.headers.get('date') : 'no response date';
    console.log('Status Code:', res.status);
    console.log('Date in Response header:', headerDate);

    const users = await res.json();

    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  } catch (err) {
    console.log(err.message); //can be console.error
  }
})();

由于 Fetch API 與瀏覽器兼容,因此您為使用 Fetch API 在瀏覽器中獲取數(shù)據(jù)而編寫的代碼也可以在 Node.js 中使用而無需修改,反之亦然。

Axios

Axios 是一個非常流行的基于 Promise 的請求庫。它是一個適用于瀏覽器和 Node.js 的 HTTP 客戶端。它還包括一些方便的功能,例如攔截請求和響應數(shù)據(jù),以及自動將請求和響應數(shù)據(jù)轉換為 JSON。

const axios = require('axios');

axios.get('https://jsonplaceholder.typicode.com/users')
  .then(res => {
    const headerDate = res.headers && res.headers.date ? res.headers.date : 'no response date';
    console.log('Status Code:', res.status);
    console.log('Date in Response header:', headerDate);

    const users = res.data;

    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  })
  .catch(err => {
    console.log('Error: ', err.message);
  });

上面的示例中的代碼比前一個示例中的代碼少,因為它使用了 Promise 鏈。但是,您可以將其變成 async/await。

解釋一下上面的例子做了什么。需要使用 axios 庫,然后使用 axios.get 方法向 JSONPlaceholder API 發(fā)出 GET 請求。使用承諾鏈來處理響應。在 then 方法回調中,將狀態(tài)代碼和日期記錄到控制臺。

Axios 將響應數(shù)據(jù)轉換為開箱即用的 JSON。上例中的響應數(shù)據(jù)是用戶數(shù)組。循環(huán)遍歷它并將用戶 ID 和名稱記錄到控制臺。

Got

Got 是 Node.js 的另一個流行的 HTTP 請求庫。 Got 具有基于承諾的 API,其 HTTP/2 支持和分頁 API 是其獨特的特點。

const got = require('got');

got.get('https://jsonplaceholder.typicode.com/users', {responseType: 'json'})
  .then(res => {
    const headerDate = res.headers && res.headers.date ? res.headers.date : 'no response date';
    console.log('Status Code:', res.statusCode);
    console.log('Date in Response header:', headerDate);

    const users = res.body;
    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  })
  .catch(err => {
    console.log('Error: ', err.message);
  });

上面的代碼示例與 Axios 類似,但有兩個主要區(qū)別:

  1. 我們需要將 {responseType: 'json'} 作為第二個參數(shù)傳遞給 get 方法,以指示響應為 JSON 格式
  2. 狀態(tài)代碼標頭稱為 statusCode ,而不是 status

其他的與之前對 axios 的要求保持一致。您可以在此拉取請求中看到上面的示例。

superagent

superagent 于 2011 年 4 月由 VisionMedia 首次發(fā)布,是最古老的 Node.js 請求包之一。 superagent 將自己定位為“小型、漸進式客戶端 HTTP 請求庫和 Node.js 模塊,具有相同的 API,支持許多高級 HTTP 客戶端功能?!彼峁┗诨卣{和基于承諾的 API。 superagent 有幾個插件,您可以使用它來擴展其功能。

const superagent = require('superagent');

(async () => {
  try {
    const res = await superagent.get('https://jsonplaceholder.typicode.com/users');
    const headerDate = res.headers && res.headers.date ? res.headers.date : 'no response date';
    console.log('Status Code:', res.statusCode);
    console.log('Date in Response header:', headerDate);

    const users = res.body;
    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  } catch (err) {
    console.log(err.message); //can be console.error
  }
})();

Superagent 已經(jīng)成熟且經(jīng)過實戰(zhàn)考驗,因此非??煽?。我們還可以使用 SuperTest 庫測試超級代理調用。與前面的示例一樣,上面的超級代理示例可作為拉取請求使用。

node-fetch

node-fetch 是 Node.js 的另一個非常流行的 HTTP 請求庫 - 根據(jù) npm 趨勢,在 2024 年 2 月的第一周,它的下載量超過 5000 萬次。

用他們自己的話來說,“node-fetch 是一個輕量級模塊,它將 Fetch API ( window.fetch ) 引入 Node.js?!逼涔δ馨ㄅc基于瀏覽器的 window.fetch 以及本機 Promise 和異步函數(shù)的一致性。

const fetch = require('node-fetch');

(async () => {
  try {
    const res = await fetch('https://jsonplaceholder.typicode.com/users');
    const headerDate = res.headers && res.headers.get('date') ? res.headers.get('date') : 'no response date';
    console.log('Status Code:', res.status);
    console.log('Date in Response header:', headerDate);

    const users = await res.json();
    for(user of users) {
      console.log(`Got user with id: ${user.id}, name: ${user.name}`);
    }
  } catch (err) {
    console.log(err.message); //can be console.error
  }
})();

讓我們回顧一下與使用 superagent 和 async/await 的示例相比的一些差異:

  • node-fetch 不需要顯式的 GET 方法; HTTP 動詞可以作為第二個參數(shù)中的 method 鍵發(fā)送,該參數(shù)是一個對象。例如: {method: 'GET'}
  • 另一個區(qū)別是標頭是一個對象,具有 get 方法來獲取標頭值。我們調用 res.headers.get('date') 來獲取日期響應頭的值

Node HTTP請求方式對比

除了內置的 HTTP/HTTPS 模塊和內置的 fetch API 之外,所有其他四個 HTTP 客戶端庫都可以作為 npm 包提供。以下是根據(jù) npm 趨勢顯示的過去六個月每周下載統(tǒng)計數(shù)據(jù)的快速概覽:

從每月下載量來看,過去六個月中,node-fetch 最受歡迎,而 superagent 則最不受歡迎。為了更全面地了解它們的受歡迎程度,讓我們檢查其他指標,從 Got GitHub 存儲庫上提供的比較表中獲取見解:

從上表來看,node-fetch 是下載次數(shù)最多的軟件包,最大安裝大小為 7.45MB。 Axios 擁有最多的 GitHub 星數(shù),達到 10.3 萬——比其他所有三個庫的總和還多。

使用 Express.js 實現(xiàn) HTTP 服務

const express = require("express");
const app = express();

const PORT = process.env.PORT || 3000;

app.get("/", (req, res) => {
  res.send("Hello world!");
});

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
});

這就是使用 Express.js 實現(xiàn)基本 HTTP 服務的方式。

處理Node HTTPS POST 請求

在本節(jié)中,我們將探討如何在 Node.js 服務器中處理 POST 請求。當用戶提交 HTML 表單或發(fā)出 AJAX POST 請求時,會發(fā)生典型的 POST 請求。

當 POST 請求到達其預期端點時,您將訪問 POST 數(shù)據(jù),在回調函數(shù)中解析它,驗證和清理數(shù)據(jù),并可能發(fā)回響應。但是,您應該意識到,在使用普通 Node.js 服務器時,解析 HTTP 請求正文可能會很乏味。

下面的代碼是普通 Node.js HTTP 服務器的基本實現(xiàn)。它有一個基本的 HTML 表單,您可以使用它來發(fā)出 POST 請求。請求正文的結構取決于編碼類型。這些編碼類型包括 application/x-www-form-urlencoded 、 multipart/form-data 和 text/plain :

const http = require("http");

const html = `
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" cnotallow="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form actinotallow="/submit-form" enctype="application/x-www-form-urlencoded" method="POST">
      <label> Enter Name: 
        <input type="text" autocomplete="name" name="name" required />
      </label>
      <input type="submit" />
    </form>
  </body>
</html>
`;
const server = http.createServer((req, res) => {
  switch (req.method) {
    case "GET":
      if (req.url === "/") {
        res.writeHead(200, { "Content-Type": "text/html" });
        res.end(html);
      } else {
        res.writeHead(404, { "Content-Type": "text/plain" });
        res.end("Page not found");
      }
      break;
    case "POST":
      if (req.url === "/submit-form") {
        let body = "";
        req.on("data", (data) => {
          body += data;
        });

        req.on("end", () => {
          console.log("Request body:  " + body);
          // Parse, validate, and sanitize
          res.writeHead(200, { "Content-Type": "application/json" });
          res.end(JSON.stringify({ body }));
        });
      } else {
        res.writeHead(404, { "Content-Type": "text/plain" });
        res.end("Page not found");
      }
      break;
    default:
      res.writeHead(405, { "Content-Type": "text/plain" });
      res.end("Method not supported");
  }
});

const PORT = process.env.PORT || 3000;

server.listen(PORT, () => {
  console.log(`Your app is listening on PORT ${PORT}`);
});

解析 POST 請求正文后,您需要驗證和清理數(shù)據(jù)。然后,您可以將數(shù)據(jù)保存在數(shù)據(jù)庫中、對用戶進行身份驗證或重定向到適當?shù)捻撁妗?/p>

大多數(shù)后端框架都具有用于解析 HTTP 請求正文的內置功能。使用 Express.js,當請求正文具有 application/x-www-form-urlencoded 編碼時,您可以使用內置的 express.urlencoded() 中間件。中間件將使用請求數(shù)據(jù)的鍵值對填充 req.body :

const express = require("express");
const path = require("path");
const app = express();

const PORT = process.env.PORT || 3000;

app.use(express.static("public"));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.post("/submit-form", (req, res) => {
  console.log(req.body);
  res.json(req.body);
});

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "index.html"));
});

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
});

對于 multipart/form-data 編碼,需要使用第三方包,例如busboy、Multer或formidable。

下面的代碼說明了如何使用 Multer。由于它不是內置中間件,因此請務必首先從 npm 包注冊表安裝它:

const express = require("express");
const path = require("path");
const multer = require("multer");
const app = express();
const upload = multer();

const PORT = process.env.PORT || 3000;

app.use(express.static("public"));

app.post("/submit-form", upload.none(), (req, res) => {
  console.log("req.body: ", req.body);
  console.log("Content-Type: ", req.get("Content-Type"));
  res.json(req.body);
});

app.get("/", (req, res) => {
  res.sendFile(path.join(__dirname, "index.html"));
});

app.listen(PORT, () => {
  console.log(`Your app is listening on port ${PORT}`);
});

最后,Express還有一個內置的中間件,用于解析具有 text/plain 編碼的請求體。它的用法與我們之前看過的中間件類似。你可以像這樣安裝它:

app.use(express.text());

總結

axios比superagent的功能列表很長,盡管 node-fetch 看起來很有前途并且安裝大小很小,但我不確定該 API 是否足夠用戶友好——至少對我來說是這樣。

您可能會注意到我的討論中省略了 Request npm 包。盡管 Request 持續(xù)受歡迎,每周下載量達到 1142 萬次,但截至 2024 年 2 月已被棄用,這使其成為一個不切實際的選擇。

所有這些庫主要做同樣的事情——就像你喜歡哪個品牌的咖啡一樣,最終你仍然在喝咖啡。根據(jù)您的用例明智地選擇,并做出正確的權衡以獲得最大利益。

責任編輯:武曉燕 來源: 宇宙一碼平川
相關推薦

2017-08-17 13:56:30

JavascriptNode.jsHttp

2023-03-24 15:57:31

Node.js應用程序容器

2023-06-16 15:14:57

Node.js容器化開發(fā)

2021-10-21 08:59:17

技術HTTP攻擊

2021-05-11 07:45:00

HTTPNode.jsCookie

2025-03-10 00:00:22

PDF圖片表格

2023-06-30 23:25:46

HTTP模塊內存

2023-10-04 07:35:03

2022-01-07 08:00:00

Node.js開發(fā)Web

2017-04-10 13:28:32

Node.jsJavaScript

2018-01-04 09:46:48

PHPHTTP

2014-03-07 13:43:32

Node.jsNode

2021-10-03 15:02:50

HTTPNodejs

2021-12-28 20:04:23

Node.js開發(fā)JavaScript

2014-09-12 10:35:09

Node.jsHTTP 206

2020-04-21 17:04:12

JavaScriptHTTP請求開發(fā)

2021-01-27 08:05:55

本地存儲HTTP

2013-11-01 09:34:56

Node.js技術

2015-03-10 10:59:18

Node.js開發(fā)指南基礎介紹

2021-12-01 00:05:03

Js應用Ebpf
點贊
收藏

51CTO技術棧公眾號