Skip to content

ExpressJS - 表单数据

Express.js - 处理表单数据和文件上传

Section titled “Express.js - 处理表单数据和文件上传”

处理来自客户端的传入数据——无论是来自 HTML 表单、JSON API 请求还是文件上传——是任何 Web 服务器的基本任务。Express 为常见数据格式提供了内置的中间件(middleware),并依赖像 Multer 这样的库来处理文件上传等更复杂的场景。

在现代版本的 Express(4.16.0+)中,解析 JSON 和 URL-encoded 请求体所需的中间件已直接包含在 Express 包中。您不再需要单独安装 body-parser 包。

import express from 'express';
const app = express();
// 1. 用于解析 JSON 请求体的中间件
// 用于 API 请求,例如来自前端框架的请求。
app.use(express.json());
// 2. 用于解析 URL-encoded 请求体的中间件
// 用于传统的 HTML 表单提交。
app.use(express.urlencoded({ extended: true }));
// 现在,您的路由将可以访问已填充的 `req.body` 对象。
app.post('/api/users', (req, res) => {
console.log('Received data:', req.body);
const { username, email } = req.body;
// 验证并处理数据...
if (!username || !email) {
return res.status(400).json({ message: 'Username and email are required.' });
}
res.status(201).json({ message: 'User created successfully!', user: req.body });
});
app.listen(3000, () => console.log('Server running on port 3000'));

您可以使用 curl 等工具测试上述端点:

# 测试 JSON 端点
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{"username":"john_doe","email":"john.doe@example.com"}'
# 测试 URL-encoded 端点
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/x-www-form-urlencoded" \
-d 'username=jane_doe&email=jane.doe@example.com'

对于处理 multipart/form-data(主要用于文件上传),标准库是 Multer。它是一个强大的中间件,会将 file 或 files 对象添加到您的请求对象中。

# 安装 Multer
npm install multer

以下是一个完整的示例,展示如何设置路由来处理单个文件上传并将其保存到服务器。

import express from 'express';
import multer from 'multer';
import path from 'path';
const app = express();
// 配置 Multer 存储
const storage = multer.diskStorage({
destination: function (req, file, cb) {
// 上传文件的目标目录
cb(null, './uploads/');
},
filename: function (req, file, cb) {
// 创建一个唯一文件名以避免覆盖
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
cb(null, file.fieldname + '-' + uniqueSuffix + path.extname(file.originalname));
}
});
// 使用存储配置初始化 Multer
const upload = multer({ storage: storage });
// 如果您希望提供文件访问,请将 'uploads' 目录设置为公共可访问
app.use('/uploads', express.static('uploads'));
// 处理文件上传的路由
// 'profileImage' 是表单字段的名称(<input type="file" name="profileImage">)
app.post('/api/upload-profile-picture', upload.single('profileImage'), (req, res) => {
if (!req.file) {
return res.status(400).send('No file uploaded.');
}
// req.file 包含有关已上传文件的信息
console.log('File uploaded:', req.file);
res.status(200).json({
message: 'File uploaded successfully!',
filename: req.file.filename,
path: req.file.path
});
});
app.listen(3000, () => console.log('Server running on port 3000'));
  • 始终验证输入:永远不要相信用户提交的数据。在处理 req.body 和 req.params 之前,使用像 express-validator 或 joi 这样的库来验证和净化它们。这有助于防止 NoSQL 注入、XSS 和其他漏洞。
  • 文件上传安全:在接受文件上传时,务必格外小心。通过文件过滤器配置 Multer,仅允许特定文件类型(例如 image/jpeg、image/png),并设置文件大小限制以防止拒绝服务攻击。
  • 使用 express.Router:为了更好的组织性,将相关的路由使用 express.Router 分组到单独的文件中,而不是将所有路由都放在主应用程序文件中。