iT邦幫忙

2022 iThome 鐵人賽

DAY 27
0
Modern Web

小白大戰基礎網頁開發系列 第 27

D27 - 實作 Node.js Project

  • 分享至 

  • xImage
  •  

昨天我們先帶大家簡單認識 Node.js 是甚麼和它在使用上的優勢與便利後, 今天要來看看該怎麼應用 Node.js!

Node.js

我們將使用 Node 來運行 Javascript 作為服務器端的程式碼。 並且使用 Express 等模組 (module), 實作 forward-facing APIs 就如同我們之前一直在使用的 AJAX fetch 的 API 一樣。

我們將定義 API 端點 (API endpoints), 然後提供在有人從該端點請求時應該運行的程式碼。如此一來, 我們就可以讀取他們的 query 參數用相關數據進行響應 (respond)

啟動 Node.js 應用程序有幾個步驟, 但大多數的項目還是遵循相同的結構。
使用 Node.js 時,你主要會使用 command line 來操作。

設定項目 & 運行服務器

  1. 啟動一個新的項目目錄(例如: node-practice
  2. 在目錄中,運行 npm init 來初始化一個 package.json 配置文件 (configuration file), 你可以一直按 Enter 來使用預設值 (defaults)
  3. 使用 npm install <package-name> 安裝任何模組 (modules)
  4. 開始編寫你的 Node.js 文件!(例如: app.js
  5. 在項目的公共目錄中可以包含任何前端文件。

在此過程中, npm 這個工具將幫助你安裝管理你在 Node 應用程序中有用的套件 (packages)

  1. 運行 npm install expressnpm install express --``save 安裝 Express.js 包, 成功安裝 Express 後會自動被存到 package.json 中。

What is Express?
http://expressjs.com/
Express4.18.1
→ Fast, unopinionated, minimalist web framework for Node.js

Node.js 模組 (Modules)

當你使用 Node.js 運行 .js 文件時, 你可以訪問 JS 中的預設函數(例如 console.log)。
而為了獲得 file i/o 或處理網路請求等功能, 你需要從模組中引入該功能 - 類似於在 Java 或 Python 中使用的 import 這個關鍵字。
在 Node.js 中, 你可以使用 require() 函數 來執行此操作, 並傳遞要引入的模塊的字符串名稱 (string name)。例如, 我們在 Node.js 中用於響應(respond) HTTP 請求的模組稱為 express。
就可以像這樣引入 Express:

const express = require("express");

app.js

實作一個簡單的 "Say hi to Pig Lin!” Express application

const express = require('express'); // 引入 library
const app = express(); // express 引入一個 function

// deal with different requests
// 參數: url, 要執行的function
app.get("/posts", function (req, res) {
  res.type("text").send("Say hi to Pig Lin!");
});

app.get("/pig", function (req, res) {
  res.send("Oink Oink!");
});

// 運行 8080 port
app.listen(8080); // 選擇使用一個不易產生衝突的 port

於瀏覽器輸入 http://localhost:8080/posts , 你就可以看到 server 回傳的文本內容:

於瀏覽器輸入 http://localhost:8080/pig:

app.get(...) 處理 GET 請求的方法
app.post(...) 處理 POST 請求的方法
req (慣例名稱) 請求物件: 有權存取請求參數等項目
res (慣例名稱) 響應物件: 具有向客戶端發送數據的方法
res.type(...) 設置“content-type”, 始終會在你的response中設置“text/plain”或“application/json”
res.send(response) 將response發送給客戶端
res.json(response) 與 res.send 相同, 不同的是這邊使用 JSON 物件

app.listen( )

當我們要啟動 localhost 服務器以運行 Express 應用程序時, 你需要指定要監聽的 port (端口)。
express app 物件有一個函數 app.listen, 它接受一個端口號(port number)callback 函數 (optional) 當參數。
另外在 app.js 的底部, 添加以下程式碼 - (當託管在實際的服務器上時, 需要 process.env.PORT 才能使用預設的端口)。

// 允許我們通過設置環境去輕鬆更改端口變數 (port variable)
const PORT = process.env.PORT || 8080; 
app.listen(PORT);

Express 中的基本 routing (路由)

routes 用於定義 Web 服務中的端點們
Express 支持不同的 HTTP 請求 — 而我們將學習 GET 和 POST 並且 Express 會嘗試按照你在程式碼中定義的順序匹配 routes。

GET

app.get(path, (req, res) => {
  ...
});

app.get 允許我們創建一個 GET 端點。 它有兩個參數: 端點 URL 路徑, 以及用於修改/發送響應的 callback 函數
向路徑添加路由(Routing)時, 你可以從請求中檢索訊息, 並使用 res 發送回響應(例如: 設置 status code、content-type 等); 然而, 如果訪問的端點在你的 Express 應用程序中沒有匹配的路由, 則響應將是 404(找不到資源)。

關於 Request 的屬性與方法:

名稱 描述
req.params 來自 request 的端點"路徑"參數
req.query 從 request 中"查詢"參數

關於 Response 的屬性與方法:

名稱 描述
res.status( ) 設定 response status code
res.sendStatus( ) 使用預設狀態文本設定 response status code
res.set( ) 設定 header 訊息, 例如: “content-type”
res.type(...) 設置“content-type”, 始終會在你的response中設置“text/plain”或“application/json”
res.send(response) 將response發送給客戶端
res.json(response) 與 res.send 相同, 不同的是這邊使用 JSON 物件
res.write(data) 在 response 中寫入 data 而不結束交互通訊

設定內容格式 (content-type)

在一般默認的情況下, 響應 (response) 的內容格式是 HTML, 儘管在我們的 Web 服務中, 我們只會發送純文本 (plain text)JSON 響應 。要更改內容格式的話, 可以使用 res.set 函數, 該函數用於設置 response header 訊息(例如: 內容格式)。
你也可以使用 res.type("text")res.type("json"), 它們分別相當於設置 text/plainapplication/json Content-Type headers。

設定 content-type 為 text/plain

 app.get('/hello', function (req, res) {
   // res.set("Content-Type", "text/plain");
   res.type("text"); // 如同上一行的 res.set 寫法
   res.send('Hello Pig Lin!');
 });

設定 content-type 為 application/json

app.get('/hello', function (req, res) {
  res.set("Content-Type", "application/json");
  res.json({ "msg" : "Hello Pig Lin!" });
});

Request 參數: 路徑參數

使用 :param 定義路由參數, 在路由中充當通配符(wildcards), 讓使用者將"變數(variable)"傳遞給端點。

Route path: /countries/:country/cities/:city
Request URL: http://localhost:8080/countries/TW/cities/Taipei
req.params: { "country": "TW", "city": "Taipei" }

以上資訊會附加到請求物件, 可以使用 req.params 來訪問

app.get("/countries/:country/cities/:city", function (req, res) {
  res.type("text");
  res.send("Send a request for " + req.params.city + ", "
    + req.params.country);
});

你也可以使用 req.query 物件在 Express 中使用 query 參數:
與路徑參數 (path parameters) 不同, 這些不包含在路徑 string 中(使用 Express 路由來匹配), 我們無法確定訪問的 query key 是否存在。如果路由需要的參數遺失了, 應該在響應中向客戶端發送錯誤。

Route path: /cityInfo
Request URL: http://localhost:8080/cityInfo?country=TW&city=Taipei
req.query: { "country": "TW", "city": "Taipei" }


app.get("/cityInfo", function (req, res) {
  let country = req.query.country; // TW
  let city = req.query.city;   // Taipei
  // do what you want with variables in the response
});

上一篇
D26 - Node.js 是甚麼?
下一篇
D28 - 淺談 Node.js - POST & Middleware & Multer
系列文
小白大戰基礎網頁開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言