在实际的 Web 开发中,客户端向服务端传递数据的方式有多种选择,不同的场景需要采用不同的传参方式。本文介绍五种最常见的 HTTP 请求传参形式:路径参数、查询参数、application/x-www-form-urlencoded、application/json 和 multipart/form-data,并基于 Express 框架给出完整的服务端处理代码,方便读者在本地测试验证。
一、路径参数(Route Parameters)
路径参数直接将值嵌入 URL 路径中,常用于标识具体资源,如用户 ID、商品 ID 等。例如 GET /users/123,其中 123 就是路径参数。在 Express 中通过路由占位符 :id 定义,服务端使用 req.params 获取。- // 服务端路由定义
- app.get('/users/:id', (req, res) => {
- const userId = req.params.id;
- res.json({ message: '获取用户信息', userId });
- });
复制代码
二、查询参数(Query Parameters)
查询参数附加在 URL 的问号 ? 之后,多个参数用 & 连接,常见于搜索、过滤、分页等场景。例如 GET /search?keyword=node&page=2。Express 通过 req.query 获取所有查询参数。- app.get('/search', (req, res) => {
- const { keyword, page } = req.query;
- res.json({ message: '查询参数已接收', keyword, page: page || 1 });
- });
复制代码
三、application/x-www-form-urlencoded
这是 HTML 表单默认的编码方式(method="post" 且未指定 enctype 时)。提交时浏览器将表单字段编码为 key=value&key2=value2 的形式,放入请求体。服务端需使用 express.urlencoded() 中间件解析。- // 前端表单(示例)
- <form action="/register" method="post">
- <input type="text" name="username" />
- <input type="password" name="password" />
- <button>submit</button>
- </form>
- // 服务端处理
- app.use(express.urlencoded({ extended: true }));
- app.post('/register', (req, res) => {
- const { username, password } = req.body;
- res.json({ username, password });
- });
复制代码
四、application/json
RESTful API 常用 JSON 格式传输复杂数据结构。前端需要设置 Content-Type: application/json,并将 JavaScript 对象序列化为 JSON 字符串。服务端使用 express.json() 中间件解析。- // 前端用 fetch 发送 JSON 请求
- fetch('/login', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ username: 'admin', password: '123456' })
- });
- // 服务端处理
- app.use(express.json());
- app.post('/login', (req, res) => {
- const { username, password } = req.body;
- res.json({ username, password });
- });
复制代码
五、multipart/form-data
文件上传必须使用 multipart/form-data,同时也可以提交普通表单字段。表单需设置 enctype="multipart/form-data",浏览器会自动生成 Content-Type 并包含 boundary 分隔符。服务端使用 multer 等中间件处理。- // 前端表单(需指定 enctype)
- <form action="/upload" method="post" enctype="multipart/form-data">
- <input type="file" name="avatar" />
- <input type="text" name="username" />
- <input type="password" name="password" />
- <button>submit</button>
- </form>
- // 服务端处理(需安装 multer)
- const multer = require('multer');
- const upload = multer({ storage: multer.memoryStorage() });
- app.post('/upload', upload.single('avatar'), (req, res) => {
- // req.file 包含上传文件信息,req.body 包含文本字段
- res.json({
- message: '文件上传成功',
- filename: req.file.originalname,
- size: req.file.size,
- mimetype: req.file.mimetype
- });
- });
复制代码
完整 Express 服务端示例
下面整合上述五种传参方式的处理逻辑,提供一个可直接运行的本地服务器。- const express = require('express');
- const cors = require('cors');
- const multer = require('multer');
- const app = express();
- const port = 3000;
- app.use(cors());
- // 解析 JSON 和 URL 编码的请求体
- app.use(express.json());
- app.use(express.urlencoded({ extended: true }));
- // 1. 路径参数
- app.get('/users/:id', (req, res) => {
- res.json({ message: '获取用户信息', userId: req.params.id });
- });
- // 2. 查询参数
- app.get('/search', (req, res) => {
- const { keyword, page } = req.query;
- res.json({ message: '查询参数已接收', keyword, page: page || 1 });
- });
- // 3. URL 编码表单
- app.post('/register', (req, res) => {
- const { username, password } = req.body;
- res.json({ username, password });
- });
- // 4. JSON 请求体
- app.post('/login', (req, res) => {
- const { username, password } = req.body;
- res.json({ username, password });
- });
- // 5. 文件上传(multipart)
- const upload = multer({ storage: multer.memoryStorage() });
- app.post('/upload', upload.single('avatar'), (req, res) => {
- res.json({
- message: '文件上传成功',
- filename: req.file.originalname,
- size: req.file.size,
- mimetype: req.file.mimetype
- });
- });
- app.listen(port, () => {
- console.log(`服务器启动:http://localhost:${port}`);
- });
复制代码
测试方法
将上述代码保存为 server.js,依次执行以下命令初始化项目并安装依赖:- npm init -y
- npm i express cors multer
- node server.js
复制代码 服务启动后,可以使用浏览器、Postman 或 curl 发送对应请求,观察服务端返回的 JSON 数据以及终端输出的日志。通过实际测试,可以更直观地理解不同传参方式在客户端构造和服务端接收上的差异。 |