最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node.js 中的 express 框架基礎(chǔ)到進階指南

 更新時間:2026年04月13日 09:42:15   作者:走粥  
文章介紹了Express框架的核心概念和進階應(yīng)用,主要涵蓋基礎(chǔ)篇(Express應(yīng)用入門、路由和中間件)及進階篇(統(tǒng)一錯誤處理、RESTful API設(shè)計、文件上傳、安全最佳實踐和性能優(yōu)化),感興趣的朋友一起看看吧

一、基礎(chǔ)篇:Express 核心概念入門

1. 第一個 Express 應(yīng)用:極簡啟動

先看一個最基礎(chǔ)的 Express 應(yīng)用,理解其核心結(jié)構(gòu):

// 引入 Express 模塊
const express = require('express');
// 創(chuàng)建 Express 應(yīng)用實例
const app = express();
// 定義端口
const PORT = 3000;
// 定義根路由:處理 GET 請求
app.get('/', (req, res) => {
  res.send('Hello Express!');
});
// 啟動服務(wù)器監(jiān)聽端口
app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

核心解析

  • express():創(chuàng)建一個 Express 應(yīng)用實例,封裝了 HTTP 服務(wù)器的創(chuàng)建和請求處理邏輯。
  • app.get(path, handler):定義路由,監(jiān)聽 path 路徑的 GET 請求,handler 是請求處理函數(shù),接收 req(請求對象)和 res(響應(yīng)對象)。
  • res.send():發(fā)送響應(yīng)內(nèi)容,自動設(shè)置 Content-Type(字符串默認(rèn) text/html,對象默認(rèn) application/json)。

2. 路由(Routing):請求的“導(dǎo)航系統(tǒng)”

路由是 Express 處理請求的核心,負(fù)責(zé)將不同的 HTTP 請求(方法+路徑)映射到對應(yīng)的處理函數(shù)。

(1)基本路由:支持所有 HTTP 方法

// GET 請求:獲取數(shù)據(jù)
app.get('/users', (req, res) => {
  res.json({ users: ['Alice', 'Bob'] });
});
// POST 請求:創(chuàng)建數(shù)據(jù)
app.post('/users', (req, res) => {
  res.status(201).json({ message: 'User created' });
});
// PUT 請求:更新數(shù)據(jù)(完整替換)
app.put('/users/:id', (req, res) => {
  res.json({ message: `User ${req.params.id} updated` });
});
// DELETE 請求:刪除數(shù)據(jù)
app.delete('/users/:id', (req, res) => {
  res.json({ message: `User ${req.params.id} deleted` });
});

(2)路由參數(shù)與查詢字符串

  • 路由參數(shù):通過 :name 定義,存儲在 req.params 中(如 /users/:id 匹配 /users/123req.params.id = '123')。
  • 查詢字符串:URL 中 ? 后的參數(shù),存儲在 req.query 中(如 /users?page=1&limit=10,req.query = { page: '1', limit: '10' })。
app.get('/users/:id/posts', (req, res) => {
  const { id } = req.params;
  const { page = 1, limit = 10 } = req.query;
  res.json({ userId: id, page, limit });
});

(3)路由模塊化:用express.Router()拆分代碼

當(dāng)路由增多時,將所有路由寫在一個文件中會導(dǎo)致代碼臃腫。使用 Router 可以將路由按模塊拆分:

// routes/users.js:用戶模塊路由
const express = require('express');
const router = express.Router();
// 注意:路徑是相對于掛載點的(這里的 '/' 對應(yīng) '/users')
router.get('/', (req, res) => res.json({ users: [] }));
router.get('/:id', (req, res) => res.json({ user: req.params.id }));
module.exports = router;
// app.js:主文件中掛載路由
const userRouter = require('./routes/users');
// 將 userRouter 掛載到 '/users' 路徑下
app.use('/users', userRouter);

(4)路由鏈:簡化同一資源的多個路由

對于同一資源(如 /users)的多個 HTTP 方法,可以用 app.route() 鏈?zhǔn)秸{(diào)用:

app.route('/users')
  .get((req, res) => res.json({ users: [] }))
  .post((req, res) => res.status(201).json({ message: 'Created' }));

3. 中間件(Middleware):Express 的“靈魂”

中間件是 Express 最核心的設(shè)計理念——它是一個函數(shù),在請求-響應(yīng)周期中被調(diào)用,可以訪問 req、resnext(下一個中間件函數(shù))。中間件可以執(zhí)行任何代碼、修改請求/響應(yīng)對象、結(jié)束請求-響應(yīng)周期,或調(diào)用下一個中間件。

(1)中間件的分類與用法

  • 應(yīng)用級中間件:綁定到 app 實例,對所有請求生效(或指定路徑生效)。
  • 路由級中間件:綁定到 express.Router() 實例,僅對該路由模塊生效。
  • 錯誤處理中間件:專門處理錯誤,有 4 個參數(shù) (err, req, res, next)。
  • 內(nèi)置中間件:Express 自帶的中間件(如 express.json、express.static)。
  • 第三方中間件:社區(qū)開發(fā)的中間件(如 morgancors)。

(2)內(nèi)置中間件:最常用的兩個

  • express.json():解析請求體中的 JSON 數(shù)據(jù)(存儲到 req.body)。
  • express.urlencoded():解析 URL 編碼的請求體(如表單提交,存儲到 req.body)。
  • express.static():托管靜態(tài)文件(如 HTML、CSS、圖片)。
// 解析 JSON 請求體(必須放在路由之前)
app.use(express.json());
// 解析 URL 編碼請求體(extended: false 表示使用 querystring 庫解析)
app.use(express.urlencoded({ extended: false }));
// 托管 public 目錄下的靜態(tài)文件(訪問 /css/style.css 對應(yīng) public/css/style.css)
app.use(express.static('public'));

(3)自定義應(yīng)用級中間件

// 全局中間件:每個請求都會執(zhí)行
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
  next(); // 調(diào)用下一個中間件,否則請求會掛起
});
// 路徑特定中間件:僅對 /api 路徑下的請求生效
app.use('/api', (req, res, next) => {
  console.log('Accessing API');
  next();
});

(4)錯誤處理中間件

錯誤處理中間件必須有 4 個參數(shù),且要放在所有中間件和路由之后:

// 模擬一個錯誤路由
app.get('/error', (req, res, next) => {
  const error = new Error('Something went wrong!');
  error.status = 500;
  next(error); // 將錯誤傳遞給錯誤處理中間件
});
// 錯誤處理中間件
app.use((err, req, res, next) => {
  const status = err.status || 500;
  const message = err.message || 'Internal Server Error';
  res.status(status).json({ error: message });
});

二、進階篇:構(gòu)建生產(chǎn)級應(yīng)用

1. 統(tǒng)一錯誤處理:優(yōu)雅處理同步與異步錯誤

Express 4.x 默認(rèn)不會捕獲異步代碼中的錯誤(如 async/await 中的 throw),需要手動包裝或使用工具。

(1)自定義錯誤類

先定義一個統(tǒng)一的錯誤類,方便傳遞狀態(tài)碼和錯誤信息:

class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.isOperational = true; // 標(biāo)記為可預(yù)期的業(yè)務(wù)錯誤(非系統(tǒng)錯誤)
    Error.captureStackTrace(this, this.constructor);
  }
}

(2)異步錯誤包裝器

用一個高階函數(shù)包裝異步路由,自動捕獲錯誤并傳遞給錯誤處理中間件:

const asyncWrapper = (fn) => {
  return (req, res, next) => {
    fn(req, res, next).catch(next); // 捕獲異步錯誤,傳遞給 next(err)
  };
};

(3)完整示例

// 路由中使用
app.get('/users/:id', asyncWrapper(async (req, res, next) => {
  const user = await User.findById(req.params.id); // 模擬異步數(shù)據(jù)庫查詢
  if (!user) {
    throw new AppError('User not found', 404); // 拋出業(yè)務(wù)錯誤
  }
  res.json({ user });
}));
// 錯誤處理中間件(區(qū)分業(yè)務(wù)錯誤和系統(tǒng)錯誤)
app.use((err, req, res, next) => {
  const { statusCode = 500, message, isOperational } = err;
  res.status(statusCode).json({
    error: isOperational ? message : 'Internal Server Error',
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack }) // 開發(fā)環(huán)境返回堆棧
  });
});

2. RESTful API 設(shè)計實踐

Express 非常適合構(gòu)建 RESTful API,核心原則是“資源導(dǎo)向”,用 HTTP 方法表示操作類型。

(1)資源命名與 HTTP 方法對應(yīng)

資源GET(獲取)POST(創(chuàng)建)PUT(完整更新)PATCH(部分更新)DELETE(刪除)
/users獲取所有用戶創(chuàng)建新用戶批量更新用戶(不推薦)批量部分更新(不推薦)刪除所有用戶(不推薦)
/users/:id獲取指定 ID 的用戶不允許替換指定 ID 的用戶部分更新指定 ID 的用戶刪除指定 ID 的用戶

(2)示例:用戶管理 API

// 模擬用戶數(shù)據(jù)
let users = [
  { id: 1, name: 'Alice', email: 'alice@example.com' },
  { id: 2, name: 'Bob', email: 'bob@example.com' }
];
// 獲取所有用戶(支持分頁)
app.get('/users', asyncWrapper(async (req, res) => {
  const { page = 1, limit = 10 } = req.query;
  const start = (page - 1) * limit;
  const end = start + parseInt(limit);
  const paginatedUsers = users.slice(start, end);
  res.json({
    data: paginatedUsers,
    page: parseInt(page),
    limit: parseInt(limit),
    total: users.length
  });
}));
// 創(chuàng)建用戶
app.post('/users', asyncWrapper(async (req, res, next) => {
  const { name, email } = req.body;
  if (!name || !email) {
    throw new AppError('Name and email are required', 400);
  }
  const newUser = { id: users.length + 1, name, email };
  users.push(newUser);
  res.status(201).json({ data: newUser });
}));

3. 文件上傳:Multer 中間件

Express 本身不支持文件上傳,需要使用第三方中間件 multer。

(1)安裝與基本配置

npm install multer
const multer = require('multer');
// 配置存儲:指定文件存儲路徑和文件名
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, 'uploads/'); // 存儲到 uploads 目錄(需提前創(chuàng)建)
  },
  filename: (req, file, cb) => {
    // 生成唯一文件名:時間戳 + 原始文件名
    const uniqueName = `${Date.now()}-${file.originalname}`;
    cb(null, uniqueName);
  }
});
// 配置文件過濾器:只允許圖片上傳
const fileFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image/')) {
    cb(null, true); // 允許上傳
  } else {
    cb(new AppError('Only images are allowed', 400), false); // 拒絕上傳
  }
};
// 初始化 Multer
const upload = multer({
  storage,
  fileFilter,
  limits: { fileSize: 5 * 1024 * 1024 } // 限制文件大小 5MB
});

(2)單文件與多文件上傳

// 單文件上傳:字段名為 avatar
app.post('/upload/avatar', upload.single('avatar'), (req, res) => {
  res.json({
    message: 'Avatar uploaded successfully',
    file: req.file // 上傳的文件信息(路徑、大小等)
  });
});
// 多文件上傳:字段名為 photos,最多 5 個
app.post('/upload/photos', upload.array('photos', 5), (req, res) => {
  res.json({
    message: 'Photos uploaded successfully',
    files: req.files // 上傳的文件數(shù)組
  });
});

4. 安全最佳實踐

生產(chǎn)環(huán)境中必須關(guān)注安全,以下是 Express 應(yīng)用的核心安全措施:

(1)Helmet:設(shè)置安全 HTTP 頭

helmet 是一個安全中間件,通過設(shè)置各種 HTTP 頭來防止常見的 Web 攻擊(如 XSS、點擊劫持)。

npm install helmet
const helmet = require('helmet');
app.use(helmet()); // 啟用所有默認(rèn)安全頭

(2)CORS:配置跨域資源共享

如果 API 被前端跨域調(diào)用,需要配置 cors 中間件。

npm install cors
const cors = require('cors');
// 允許所有來源(開發(fā)環(huán)境用)
app.use(cors());
// 或僅允許特定來源(生產(chǎn)環(huán)境用)
app.use(cors({
  origin: 'https://your-frontend.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization']
}));

(3)速率限制:防止暴力攻擊

express-rate-limit 限制同一 IP 的請求頻率。

npm install express-rate-limit
const rateLimit = require('express-rate-limit');
// 全局速率限制:15 分鐘內(nèi)最多 100 個請求
const globalLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  message: 'Too many requests, please try again later'
});
app.use(globalLimiter);
// 登錄接口單獨限制:15 分鐘內(nèi)最多 5 個請求
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: 'Too many login attempts, please try again later'
});
app.post('/login', loginLimiter, (req, res) => {
  res.json({ message: 'Login successful' });
});

(4)輸入驗證:防止惡意數(shù)據(jù)

joiexpress-validator 驗證請求參數(shù)和請求體。

npm install joi
const Joi = require('joi');
// 定義用戶創(chuàng)建的驗證 schema
const userSchema = Joi.object({
  name: Joi.string().min(2).max(30).required(),
  email: Joi.string().email().required(),
  age: Joi.number().integer().min(18).max(100)
});
// 在路由中使用
app.post('/users', (req, res, next) => {
  const { error } = userSchema.validate(req.body);
  if (error) {
    throw new AppError(error.details[0].message, 400);
  }
  next(); // 驗證通過,繼續(xù)處理
}, (req, res) => {
  res.json({ message: 'User created' });
});

5. 性能優(yōu)化

生產(chǎn)環(huán)境中需要關(guān)注性能,以下是幾個核心優(yōu)化點:

(1)壓縮響應(yīng):使用compression中間件

npm install compression
const compression = require('compression');
app.use(compression()); // 壓縮所有響應(yīng)(放在路由之前)

(2)靜態(tài)文件緩存

給靜態(tài)文件設(shè)置 maxAge,讓瀏覽器緩存:

app.use(express.static('public', {
  maxAge: '1d' // 緩存 1 天
}));

(3)避免同步操作

所有 I/O 操作(數(shù)據(jù)庫、文件系統(tǒng))都使用異步方式,避免阻塞事件循環(huán)。

到此這篇關(guān)于node.js 中的 express 框架基礎(chǔ)到進階指南的文章就介紹到這了,更多相關(guān)node.js express 框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • NODE.JS加密模塊CRYPTO常用方法介紹

    NODE.JS加密模塊CRYPTO常用方法介紹

    這篇文章主要介紹了NODE.JS加密模塊CRYPTO常用方法介紹,需要的朋友可以參考下
    2014-06-06
  • 利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟

    利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟

    最近工作中遇到一個需求,大致需求就是將Excel文件在導(dǎo)入時解析為json格式轉(zhuǎn)換數(shù)據(jù)結(jié)構(gòu)再傳輸給后臺,下面這篇文章主要給大家介紹了關(guān)于如何利用Node轉(zhuǎn)換Excel成JSON的詳細(xì)步驟,需要的朋友可以參考下
    2022-11-11
  • npm安裝時的錯誤排查的方法

    npm安裝時的錯誤排查的方法

    在我們的日常工作中,使用npm來安裝依賴是非常常見的,然而,有時候安裝過程中會遇到各種各樣的報錯,本文主要介紹了npm安裝時的錯誤排查的方法,感興趣的可以了解一下
    2024-08-08
  • 關(guān)于express與koa的使用對比詳解

    關(guān)于express與koa的使用對比詳解

    很多人都在問到底該用Koa還是express,所以下面這篇文章就來給大家再次的對比了關(guān)于express與koa的相關(guān)資料,通過對比大家可以更好的進行選擇,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • 詳解用node-images 打造簡易圖片服務(wù)器

    詳解用node-images 打造簡易圖片服務(wù)器

    本篇文章主要介紹了詳解用node-images 打造簡易圖片服務(wù)器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • node.js中的fs.writeSync方法使用說明

    node.js中的fs.writeSync方法使用說明

    這篇文章主要介紹了node.js中的fs.writeSync方法使用說明,本文介紹了fs.writeSync的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • nodejs和php實現(xiàn)圖片訪問實時處理

    nodejs和php實現(xiàn)圖片訪問實時處理

    這篇文章主要為大家詳細(xì)介紹了nodejs和php分別實現(xiàn)圖片訪問實時處理,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • node.js中使用ejs渲染數(shù)據(jù)的代碼實現(xiàn)

    node.js中使用ejs渲染數(shù)據(jù)的代碼實現(xiàn)

    這篇文章主要介紹了node.js中使用ejs渲染數(shù)據(jù),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • 在Node.js應(yīng)用中使用Redis的方法簡介

    在Node.js應(yīng)用中使用Redis的方法簡介

    這篇文章主要介紹了在Node.js應(yīng)用中使用Redis的方法,最簡單的數(shù)據(jù)讀寫操作相關(guān),需要的朋友可以參考下
    2015-06-06
  • 詳解本地Node.js服務(wù)器作為api服務(wù)器的解決辦法

    詳解本地Node.js服務(wù)器作為api服務(wù)器的解決辦法

    本篇文章主要介紹了詳解本地Node.js服務(wù)器作為api服務(wù)器的解決辦法,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02

最新評論

达州市| 周宁县| 深圳市| 呼和浩特市| 威远县| 双峰县| 镇赉县| 五峰| 两当县| 自贡市| 手游| 崇左市| 方正县| 桂平市| 麻阳| 清远市| 盐津县| 阿拉善盟| 红原县| 华池县| 万山特区| 红安县| 栖霞市| 全州县| 云林县| 恭城| 冕宁县| 新泰市| 济宁市| 巴彦县| 明溪县| 伊宁县| 梅州市| 曲阳县| 平远县| 合作市| 安泽县| 高安市| 广州市| 郴州市| 石棉县|