Express 入门指南(超详细教程)
一、安装
1. 安装node.js,准备node环境
2. 创建新文件夹,运行 npm init 创建package.json
npm init
3. 安装express
npm install express
4. 根目录新建 app.js
const express = require('express')
const app = express()
const port = 3000app.get('/', (req, res) => {res.send('Hello World!')
})app.listen(port, () => {console.log(`Example app listening on port ${port}`)
})
5.在package.json的scripts中增加命令
"scripts": {"dev": "node app.js",},
6. 本地运行
npm run dev
7. 浏览器中加载 http://localhost:3000/
二、路由
1. 基本路由
app.get('/', (req, res) => {res.send('Hello World!')
})
2. 不同HTTP方法的路由
app.get('/users', (req, res) => {res.json({ message: 'GET: 获取用户列表' })
})app.post('/users', (req, res) => {res.json({ message: 'POST: 创建新用户', data: req.body })
})app.put('/users/:id', (req, res) => {res.json({ message: `PUT: 更新用户ID为 ${req.params.id}`, data: req.body })
})app.delete('/users/:id', (req, res) => {res.json({ message: `DELETE: 删除用户ID为 ${req.params.id}` })
})
3. 动态路由参数
GET请求
app.get('/users/:id', (req, res) => {const userId = req.params.idres.json({ message: `获取用户ID为 ${userId} 的信息` })
})
// 示例请求: GET http://localhost:3000/users/123
// 输出: { message: "获取用户ID为 123 的信息" }
POST请求
app.post('/users/:id', (req, res) => {const userId = req.params.idconst data = req.body //req.body 默认值为 undefined,关于该参数的具体处理方式将在下文详细说明res.json({ message: `为用户ID为 ${userId} 创建资源`, data })
})
// 示例请求: POST http://localhost:3000/users/123
// 请求体: { "name": "Tom" }
// 输出: { message: "为用户ID为 123 创建资源", data: { name: "Tom" } }
4. 多个路由参数
app.get('/users/:userId/posts/:postId', (req, res) => {const { userId, postId } = req.paramsres.json({ message: `用户 ${userId} 的帖子 ${postId}` })
})
// 示例请求: GET http://localhost:3000/users/5/posts/42
// 输出: { message: "用户 5 的帖子 42" }
5. 响应方法
方法 | 描述 |
---|---|
res.download() | 提示要下载的文件 |
res.end() | 结束响应过程 |
res.json() | 发送 JSON 响应 |
res.jsonp() | 发送带有 JSONP 支持的 JSON 响应 |
res.redirect() | 重定向请求 |
res.render() | 渲染视图模板 |
res.send() | 发送各种类型的响应 |
res.sendFile() | 将文件作为八位字节流发送 |
res.sendStatus() | 设置响应状态码并将其字符串表示形式作为响应正文发送 |
三、静态文件
要提供静态文件,例如图像、CSS 文件和 JavaScript 文件,请使用 Express 中的 express.static
内置中间件函数。
express.static(root, [options])
root 参数指定提供静态资产的根目录。有关 options 参数的更多信息,请参阅 express.static。
例如,使用以下代码在名为 public 的目录中提供图像:
app.use(express.static('public'))
//更安全写法
app.use(express.static(path.join(__dirname, 'public')))
//现在,您可以加载 public 目录中的文件:
http://localhost:3000/images/xxxx.png
四、中间件
1. 应用中间件
没有挂载路径的中间件函数。每次应用收到请求时都会执行该函数。
const express = require("express");
const app = express();// 对所有请求生效
app.use((req, res, next) => {console.log("Time:", Date.now());next();
});
挂载在/user/:id
路径上的中间件函数。该函数针对 /user/:id
路径上的任何类型的 HTTP 请求执行。
app.use('/user/:id', (req, res, next) => {console.log('Request Type:', req.method)next()
})
2. 路由中间件
const express = require('express')
const app = express()
const router = express.Router()// 没有挂载路径的中间件功能。对路由器的每个请求都执行此代码
router.use((req, res, next) => {console.log('Time:', Date.now())next()
})// 一个中间件子栈显示针对/user/:id路径的任何类型HTTP请求的请求信息
router.use('/user/:id', (req, res, next) => {console.log('Request URL:', req.originalUrl)next()
}, (req, res, next) => {console.log('Request Type:', req.method)next()
})// 在主应用上挂载路由
app.use('/', router)
3. 错误中间件
//必须接收 4 个参数 (err, req, res, next):
app.use((err, req, res, next) => {console.error(err.stack);res.status(500).send("Something broke!");
});
4. 内置中间件
express.static
提供静态资源,例如 HTML 文件、图像等。express.json
使用 JSON 有效负载解析传入请求。注意:可用于 Express 4.16.0+express.urlencoded
使用 URL 编码的负载解析传入的请求。注意:可用于 Express 4.16.0+
5. 第三方中间件
社区提供的中间件,需额外安装:
- morgan:HTTP 请求日志。
- helmet:增强安全性(设置 HTTP 头)。
- cors:跨域资源共享(CORS)。
- passport:身份认证。
示例:
const morgan = require("morgan");
const helmet = require("helmet");app.use(morgan("dev")); // 日志记录
app.use(helmet()); // 安全防护
五、req.body
Express 默认不会解析 HTTP 请求的 body 数据(如 JSON 或表单数据),因此 req.body
初始值为 undefined
。要解析请求体,可以使用内置的 express.json()
和 express.urlencoded()
中间件,或者选择第三方 body-parser
中间件。
const express = require('express');
const app = express();// 解析 JSON 格式的请求体(Content-Type: application/json)
app.use(express.json());// 解析表单数据(Content-Type: application/x-www-form-urlencoded)
app.use(express.urlencoded({ extended: true }));// 现在 req.body 可以正常获取数据了
app.post('/users/:id', (req, res) => {const userId = req.params.id;const data = req.body;console.log(data); // 这里会打印请求体数据res.json({ message: `为用户ID为 ${userId} 创建资源`, data });
});app.listen(3000, () => {console.log('Server is running on http://localhost:3000');
});
注意点
如果是 JSON 数据,确保请求头包含:
Content-Type: application/json
如果是表单数据,确保请求头包含:
Content-Type: application/x-www-form-urlencoded
六、跨越处理
1. 使用 cors 中间件
cors 是 Express 最常用的跨域解决方案,支持灵活配置。
2. 安装 cors
npm install cors
3. 基本用法(允许所有跨域请求)
const express = require("express");
const cors = require("cors");
const app = express();// 允许所有来源的请求
app.use(cors());app.get("/data", (req, res) => {res.json({ message: "跨域请求成功!" });
});app.listen(3000, () => {console.log("Server running on http://localhost:3000");
});
七、文件上传
multer
是 Express 最常用的文件上传中间件,支持单文件、多文件、限制文件类型等功能。
1. 安装 multer
npm install multer
2. 基本用法
单文件上传
const express = require("express");
const multer = require("multer");
const path = require("path");const app = express();
const upload = multer({ dest: "uploads/" }); // 文件存储目录// 单文件上传(字段名 "file")
app.post("/upload", upload.single("file"), (req, res) => {console.log(req.file); // 上传的文件信息res.send("文件上传成功!");
});app.listen(3000, () => {console.log("Server running on http://localhost:3000");
});
前端 HTML 示例:
<form action="http://localhost:3000/upload" method="post" enctype="multipart/form-data"><input type="file" name="file" /><button type="submit">上传</button>
</form>
3. 多文件上传
// 多文件上传(字段名 "files",最多 5 个文件)
app.post("/upload-multiple", upload.array("files", 5), (req, res) => {console.log(req.files); // 文件数组res.send("多文件上传成功!");
});
4. 自定义存储 & 文件名
const storage = multer.diskStorage({destination: (req, file, cb) => {cb(null, "uploads/"); // 存储目录},filename: (req, file, cb) => {// 文件名:时间戳 + 原始后缀const ext = path.extname(file.originalname);cb(null, Date.now() + ext);},
});const upload = multer({ storage });
5.限制文件类型
const upload = multer({storage,fileFilter: (req, file, cb) => {const allowedTypes = ["image/jpeg", "image/png"];if (!allowedTypes.includes(file.mimetype)) {return cb(new Error("仅支持 JPG/PNG 文件"));}cb(null, true);},limits: { fileSize: 5 * 1024 * 1024 }, // 限制 5MB
});
6. 错误处理
// 捕获 multer 错误
app.use((err, req, res, next) => {if (err instanceof multer.MulterError) {res.status(400).send(`文件上传错误: ${err.message}`);} else {next(err);}
});
八、连接数据库
1. 数据库部分
1.1 新增连接
1.2 新建数据库
1.3 新增user表
1.4 添加一条数据
2. express部分
2.1 安装 mysql2
npm install mysql2
2.2 基本连接与查询
const express = require("express");
const mysql = require("mysql2");
const app = express();// 创建数据库连接池
const pool = mysql.createPool({host: "localhost", // 数据库地址user: "root", // 用户名password: "root", // 密码database: "manage", // 数据库名waitForConnections: true,connectionLimit: 10, // 连接池大小queueLimit: 0,
});// 测试连接
pool.getConnection((err, connection) => {if (err) {console.error("数据库连接失败:", err.stack);return;}console.log("数据库连接成功,线程ID:", connection.threadId);connection.release(); // 释放连接回连接池
});// 查询示例
app.get("/user", (req, res) => {pool.query("SELECT * FROM user", (err, results) => {if (err) {return res.status(500).json({ error: err.message });}res.json(results);});
});app.listen(3000, () => {console.log("Server running on http://localhost:3000");
});