1.9 Express

Express 是一個基于 Node.js 平臺的輕量級、靈活的 Web 應用框架,它為構建 Web 應用和 API 提供了一系列強大的功能。

核心特性

  1. 中間件支持:Express 使用中間件(middleware)函數來處理 HTTP 請求和響應。中間件可以訪問請求對象(req)、響應對象(res),以及應用程序的請求-響應循環中的下一個中間件函數。通過中間件,你可以執行各種任務,如日志記錄、解析請求體、路由處理等。

  2. 路由:Express 提供了簡潔而靈活的路由機制,允許你根據不同的 HTTP 方法(GET, POST 等)和 URL 路徑定義處理邏輯。你可以創建復雜的路由結構,并且支持動態路由參數。

  3. 視圖系統:Express 支持多種模板引擎,如 EJS、Pug、Handlebars 等,使得你可以輕松地生成 HTML 頁面。

  4. 錯誤處理:內置錯誤處理機制,可以通過特定的中間件來捕獲并處理應用中的錯誤。

  5. 與數據庫集成:雖然 Express 本身不綁定任何數據庫,但其靈活性意味著它可以輕松地與 MongoDB、MySQL、PostgreSQL 等數據庫集成。

快速入門

安裝 Express:

npm install express --save

創建一個簡單的服務器:

const express = require('express');
const app = express();app.get('/', (req, res) => {res.send('Hello World!');
});app.listen(3000, () => {console.log('Server is running on port 3000.');
});

Express兼容原生http響應

Express 中,響應對象(res)是對 Node.js 原生 http.ServerResponse 對象的擴展,因此它兼容原生 HTTP 的響應方法。這意味著你可以使用原生的方法,也可以使用由 Express 提供的更高級的 API 來發送響應。

//原生 Node.js:
//使用 res.statusCode、res.setHeader、res.writeconst express = require('express');
const http = require('http');const app = express();// Express 中間件處理
app.use((req, res, next) => {// 原生 HTTP 響應方法示例res.statusCode = 200;res.setHeader('Content-Type', 'text/plain');res.write('Hello from Express with native HTTP!');// 繼續 Express 流程next();
});// Express 路由處理
app.get('/', (req, res) => {// 可以繼續使用 Express APIres.end(' (with Express finish)');
});app.listen(3000, () => {console.log('Server running on port 3000');
});

原生 Node.js: 需要手動設置狀態碼為 3xx 并設置 Location 頭。

response.writeHead(302, {Location: 'http://example.com'});
response.end();

Express: 使用便捷的 .redirect() 方法。

res.redirect('http://example.com');

Express 提供了便捷的方法如 .download() 和直接使用流(Stream)來響應文件下載請求。

這是 Express 特有的方法,用于觸發文件下載,并自動設置適當的響應頭(如 Content-Disposition: attachment)。

const express = require('express');
const app = express();
const path = require('path');app.get('/download', (req, res) => {const filePath = path.join(__dirname, 'public', 'example.txt');res.download(filePath); // 自動觸發下載
});

參數說明:

  • res.download(filePath, [filename], [options], [callback])
    • filePath: 文件在服務器上的路徑。
    • [filename]: 客戶端看到的文件名(可選,默認為原始文件名)。
    • [options]: 可選配置對象,例如?{ headers: { ... } }
    • [callback]: 下載完成后的回調函數。

原生 http 的方法時,你需要手動控制所有流程,包括讀取文件、設置響應頭、發送數據等

// const http = require('http');
const fs = require('fs');
const path = require('path');
const express = require('express');const app = express();// const server = http.createServer((req, res) => {
//   if (req.url === '/download') {
//     const filePath = path.join(__dirname,  'example.txt');//     res.writeHead(200, {
//       'Content-Type': 'application/octet-stream',
//       'Content-Disposition': 'attachment; filename="example.txt"'
//     });//     const readStream = fs.createReadStream(filePath);
//     readStream.pipe(res);
//   } else {
//     res.writeHead(404);
//     res.end('Not Found');
//   }
// });// server.listen(3000, () => {
//   console.log('Server running on port 3000');
// });app.get('/download', (req, res) => {const filePath = path.join(__dirname,  'example.txt');res.writeHead(200, {'Content-Type': 'application/octet-stream','Content-Disposition': 'attachment; filename="example.txt"'});const readStream = fs.createReadStream(filePath);readStream.pipe(res);
});app.listen(3000, () => {console.log('Server running on port 3000');});

express 特有的響應客戶端方法

res.send()

自動根據傳入數據類型設置合適的響應頭,并發送響應體。

  • 如果是字符串:默認設置?Content-Type: text/html
  • 如果是對象或數組:自動調用?JSON.stringify(),并設置?Content-Type: application/json
  • 支持 Buffer 數據(如二進制)
res.send('Hello World'); // 發送 HTML 或純文本
res.send({ name: 'Tom' }); // 自動轉為 JSON 并設置 Content-Type: application/json
res.send(Buffer.from('ABC')); // 發送二進制數據
  • 智能處理不同類型的數據。
  • 不會觸發瀏覽器下載行為。
  • 適合返回 API 響應、HTML 頁面等。

res.json()

專門用于發送 JSON 格式的數據,自動調用 JSON.stringify() 并設置 Content-Type: application/json

res.json({ success: true, data: { id: 1 } });
// 輸出:
// {"success":true,"data":{"id":1}}
  • 保證響應內容為標準 JSON 格式。

  • 設置正確的?Content-Type
  • 推薦用于構建 RESTful API。

?? 注意:如果傳入的是一個循環引用的對象,json() 會拋出錯誤。


res.sendFile()

用于發送一個文件給客戶端(例如 HTML 文件、圖片等),常用于靜態資源服務。

const path = require('path');app.get('/', (req, res) => {res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
  • 必須傳入文件的絕對路徑(推薦使用?path.join()?構造)。

  • 自動設置適當的 MIME 類型(如?text/html,?image/png?等)。
  • 不會強制瀏覽器下載,而是嘗試在瀏覽器中直接顯示(如 PDF、圖片等)。
?res.status(code)
  • 用途:設置 HTTP 狀態碼。通常與其他響應方法鏈式使用。
  • res.status(404).send('Not Found');
?res.set(field [, value])?或?res.header(field [, value])
  • 用途:設置 HTTP 響應頭。
  • res.set('Content-Type', 'text/plain');
    // 或者
    res.set({'Content-Type': 'text/plain','ETag': '12345'
    });
?res.type(type)?或?res.contentType(type)
  • 用途:設置 Content-Type 響應頭。type?參數可以是 MIME 類型或文件擴展名。
  • res.type('.html'); // Content-Type 設置為 text/html
    res.type('json'); // Content-Type 設置為 application/json

路由(Routing)

處理不同路徑和 HTTP 方法的請求。

基本路由
// GET 請求
app.get('/users', (req, res) => { /* ... */ });// POST 請求
app.post('/users', (req, res) => { /* ... */ });// 動態路由參數
app.get('/users/:id', (req, res) => {const userId = req.params.id;res.send(`User ${userId}`);
});
路由分組

使用?express.Router?創建模塊化路由:

// routes/users.js
const router = require('express').Router();router.get('/', (req, res) => { /* 獲取所有用戶 */ });
router.post('/', (req, res) => { /* 創建用戶 */ });module.exports = router;// main.js
const userRoutes = require('./routes/users');
app.use('/api/users', userRoutes);

?中間件(Middleware)

Express 中,中間件是處理 HTTP 請求的核心機制,它允許你在請求到達路由處理函數之前或之后執行代碼。中間件函數可以:

  1. 修改請求和響應對象(如添加屬性、設置頭部)
  2. 結束請求 - 響應循環(如返回錯誤或結果)
  3. 調用下一個中間件函數(通過?next()

內置中間件

// 解析 JSON 請求體
app.use(express.json());// 靜態文件服務
app.use(express.static('public'));//有時你可能希望為靜態文件添加一個路徑前綴,可以通過將掛載點作為第一個參數傳遞給 express.static 實現:
app.use('/static', express.static('public'));
// 現在,你需要通過 /static/example.html 來訪問 public 目錄下的 example.html 文件//默認情況下,如果 express.static 找不到請求的文件,它不會發送下一個中間件。如果你想改變這種行為,可以讓它繼續執行后續的中間件:app.use(express.static('public', { fallthrough: true }));app.use((req, res, next) => {res.status(404).send('Sorry, we cannot find that!');
});
// 這將確保當靜態文件未找到時,仍然有機會返回自定義的 404 頁面或其他內容。

自定義中間件

中間件函數接收三個參數:(req, res, next)

  • req:HTTP 請求對象
  • res:HTTP 響應對象
  • next:指向下一個中間件的函數,必須調用它才能繼續執行后續中間件
// 日志中間件
app.use((req, res, next) => {console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);next(); // 傳遞控制權給下一個中間件
});// 錯誤處理中間件(必須有 4 個參數)
app.use((err, req, res, next) => {console.error(err);res.status(500).send('Internal Server Error');
});

中間件的類型

1.?應用級中間件

綁定到?app?實例,處理所有路由請求:

// 記錄所有請求的時間戳
app.use((req, res, next) => {req.requestTime = Date.now();next();
});
2.?路由級中間件

綁定到特定路由,只處理匹配的請求:

// 僅處理 /users 路徑的請求
app.use('/users', (req, res, next) => {console.log('Processing user-related request');next();
});

3.?錯誤處理中間件

接收四個參數?(err, req, res, next),用于捕獲和處理錯誤:

app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send('Internal Server Error');
});

錯誤處理

錯誤處理中間件與普通中間件類似,但需要四個參數,其簽名如下:(err, req, res, next)。即使你不使用 next 參數,也必須指定它,以便 Express 能夠識別這是一個錯誤處理中間件。

統一處理應用中的異常:


app.get('/users',(req, res) => {try {const data = getData();req.data = data;next();} catch (err) {next(err); // 將錯誤傳遞給錯誤處理中間件}
});// 全局錯誤處理
app.use((err, req, res, next) => {const statusCode = err.statusCode || 500;res.status(statusCode).json({error: {message: err.message,status: statusCode}});
});

關鍵點解釋

  1. 觸發錯誤:在任何地方調用?next()?并傳入一個錯誤對象,就可以將控制權交給第一個匹配的錯誤處理中間件。
  2. 錯誤處理中間件:使用?app.use()?來定義,它會捕捉所有通過?next(err)?傳遞過來的錯誤。
  3. 環境變量判斷:在這個例子中,根據應用程序環境(development?或?production),決定是否向客戶端暴露詳細的錯誤信息。這有助于保護生產環境下的敏感信息泄露。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/83417.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/83417.shtml
英文地址,請注明出處:http://en.pswp.cn/web/83417.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面壁智能MiniCPM4.0技術架構與應用場景

📋 目錄 1. 引言:端側智能新時代2. MiniCPM4.0概述3. 核心技術架構 3.1 高效雙頻換擋機制3.2 稀疏注意力機制3.3 系統級優化創新 4. 技術突破與性能表現5. 應用場景深度解析 5.1 智能手機應用5.2 智能家居場景5.3 汽車智能化5.4 其他端側應用 6. 行業影…

RabbitMQ路由核心解密:從Exchange到RoutingKey的深度實踐與避坑指南

🔍 RabbitMQ路由核心解密:從Exchange到RoutingKey的深度實踐與避坑指南 “消息去哪了?”——這是每位RabbitMQ使用者在調試時最常發出的靈魂拷問。 理解Exchange與RoutingKey的協作機制,正是解開路由謎題的關鍵鑰匙。 一、Exchang…

Spring MVC完全指南 - 從入門到精通

目錄 1. Spring MVC簡介 2. MVC架構模式 3. Spring MVC核心組件 4. 請求處理流程 5. 控制器詳解 6. 請求映射 7. 參數綁定 8. 數據驗證 9. 視圖解析器 10. 模型數據處理 11. 異常處理 12. 攔截器 13. 文件上傳下載 14. RESTful API 15. 配置詳解 總結 1. Sprin…

實戰使用docker compose 搭建 Redis 主從復制集群

文章目錄 前言技術積累1、Redis 主從復制機制2、Docker Compose 編排3、 Redis 配置文件定制4、 驗證主從狀態5、 自動化部署與維護 環境準備實戰演示創建redis目錄及配置1、創建redis目錄2、創建redis配置文件 啟動redis集群服務1、創建docker-compose編排文件2、編排docker-c…

【學習筆記】RTSP-Ovnif-GB28181

【學習筆記】RTSP-Ovnif-GB28181 一、RTSP_RTP_RTCP RTSP(Real Time Streaming Protocol),RFC2326,實時流傳輸協議,是TCP/IP協議體系中的一個應用層協議。 RTP協議詳細說明了在互聯網上傳遞音頻和視頻的標準數據包格…

stm32-c8t6實現語音識別(LD3320)

目錄 LD3320介紹: 功能引腳 主要特色功能 通信協議 端口信息 開發流程 stm32c8t6代碼 LD3320驅動代碼: LD3320介紹: 內置單聲道mono 16-bit A/D 模數轉換內置雙聲道stereo 16-bit D/A 數模轉換內置 20mW 雙聲道耳機放大器輸出內置 5…

RAG技術全解析:從概念到實踐,構建高效語義檢索系統——嵌入模型與向量數據庫搭建指南

一、RAG技術概述:為什么需要RAG? 1.1 什么是RAG? RAG(Retrieval-Augmented Generation)是一種結合檢索與生成能力的AI架構。其核心思想是通過外部知識庫動態增強大語言模型(LLM)的生成能力&…

【資源分享】手機玩轉經典游戲!小雞模擬器1.9.0:PSP/NDS/GBA完美運行!

阿燦今天給大家推薦一款小雞模擬器,這是一個老款PC和掌上游戲機模擬器。完美模擬街機(fbamamemameplus).PS、PSP、FC(NES)SFC(SNES)、GBA、GBC、MD、NDS、DC、NGP、WS (WSC) PCE、ONS 等18款經典掌機游戲機。小雞模擬器同時也提供海量熱門的漢化版游戲免…

matlab脈沖信號并繪制波形2025.6.11

以下是一個使用MATLAB生成5V、10MHz脈沖信號并繪制波形的示例代碼: % 5V 10MHz脈沖信號仿真 clc; clear; close all; % 參數設置 voltage = 5; % 信號幅度(V) frequency = 10e6; % 脈沖頻率(10MHz) duty_cycle =

ElasticJob初探

依賴版本 JDK版本是&#xff1a;jdk17 springboot版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version></parent>zookeeper elasticjo…

【Vue3】(三)vue3中的pinia狀態管理、組件通信方式及總結、插槽

目錄 一、vue3的pinia 1、什么是pinia&#xff1f; 2、為什么Vue3選擇pinia&#xff1f; 3、使用pinia的好處 4、安裝pinia 2、項目配置 3、存儲/讀取pinia中的數據 4、修改pinia中的數據 5、storeToRefs&#xff08;保持store中數據的響應式&#xff09; 6、getters 7、…

WEB3全棧開發——面試專業技能點P1Node.js / Web3.js / Ethers.js

一、Node.js 事件循環 Node.js 的事件循環&#xff08;Event Loop&#xff09;是其異步編程的核心機制&#xff0c;它使得 Node.js 可以在單線程中實現非阻塞 I/O 操作。 &#x1f501; 簡要原理 Node.js 是基于 libuv 實現的&#xff0c;它使用事件循環來處理非阻塞操作。事件…

大數據學習棧記——Neo4j的安裝與使用

本文介紹圖數據庫Neofj的安裝與使用&#xff0c;操作系統&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安裝 Neofj可以進行官網安裝&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我這里安裝是添加軟件源的方法 最新版…

web架構4------(nginx常用變量,nginx中英文自動匹配,lnmp網站架構,正向代理,反向代理,負載均衡)

一.前言 本期來介紹nginx最后幾個知識點&#xff0c;看著要說的內容很多&#xff0c;其實一點也不多&#xff0c;都是所見即所得的東西。 二.nginx常用變量 2.1 常用變量 $args 請求中的參數&#xff0c;也叫查詢參數&#xff0c;如www.123.com/1.php?a1&b2的$args就是…

openeuler系統(CentOs)圖形化桌面黑屏/丟失(開啟VNC服務沖突)

1. VNC服務開啟如下&#xff1a; https://zhuanlan.zhihu.com/p/5049263261 在centos8系統上使用tigervnc-server搭建VNC_centos8 tigervnc-server-CSDN博客 2. 上述操作完成后&#xff0c;連接VNC仍會出現黑屏&#xff0c;則需要編輯/root/.vnc/xstartup&#xff1a; [運維…

MySQL:Prepared Statement 預處理語句

預處理語句&#xff08;Prepared Statements&#xff09;是 MySQL 中一種用于執行 SQL 查詢的高效、安全的方法。通過使用預處理語句&#xff0c;可以顯著提升查詢性能&#xff0c;并防止 SQL 注入攻擊。本文將詳細介紹 MySQL 預處理語句的概念、使用方法及其優勢。 一、預處理…

EPPLUS——CAD c#讀寫EXCEL的第三方庫

EPPLUS(可支持NET35) 在 CAD 的 C# 二次開發中&#xff0c;使用 EPPLUS 庫處理 Excel 文件具有以下顯著優點&#xff0c;尤其在兼容性、便捷性和性能等方面契合 CAD 項目的需求&#xff1a; 1. 跨.NET 版本兼容性強&#xff0c;適配 CAD 多環境部署 多框架支持&#xff1a;EP…

Linux知識回顧總結----進程狀態

本章將會介紹進程的一些概念&#xff1a;馮諾伊曼體系結構、進程是什么&#xff0c;怎么用、怎么表現得、進程空間地址、物理地址、虛擬地址、為什么存在進程空間地址、如何感性得去理解進程空間地址、環境變量是如何使用的。 目錄 1. 馮諾伊曼體系結構 1.1 是什么 1.2 結論 …

微信小程序之bind和catch

這兩個呢&#xff0c;都是綁定事件用的&#xff0c;具體使用有些小區別。 官方文檔&#xff1a; 事件冒泡處理不同 bind&#xff1a;綁定的事件會向上冒泡&#xff0c;即觸發當前組件的事件后&#xff0c;還會繼續觸發父組件的相同事件。例如&#xff0c;有一個子視圖綁定了b…

Android Test3 獲取的ANDROID_ID值不同

Android Test3 獲取的ANDROID_ID值不同 這篇文章來說明上一篇文章中說到的一個現象&#xff1a;在同一個項目中&#xff0c;創建不同的 app module&#xff0c;運行同一段測試代碼&#xff0c;獲取到的 ANDROID_ID 的值不同。 我也是第一次認真研究這個現象&#xff0c;這個還…