4. 通过查询字符串传递参数
查询字符串(Query String)是 URL 中 ? 后的键值对序列,在前端路由传参中最常见。本章讲解三种传参方式:手写拼接、使用 URLSearchParams 对象、处理多参数与可选参数,并覆盖调试、部署、常见错误与性能优化。
4.1 原理与实现流程
浏览器向服务器或 SPA 路由发送请求时,将查询参数附加在 URL 尾部。前后端均可通过解析该字符串获取参数。核心流程如下:
- 构造 URL:在基础路径后添加
?开始查询部分。 - 拼接键值对:
key=value形式,多参数间用&连接。 - 编码:特殊字符(空格、中文、符号)必须进行百分号编码。
- 传递:发起请求(
fetch、XMLHttpRequest或直接导航)。 - 解析:服务端或客户端通过
URLSearchParams或正则提取参数。
关键区别:手动拼接适合极简场景,但容易遗漏编码或引入错误;
URLSearchParams 提供标准化的增删改查,自动编码,推荐用于现代应用。
提示:在 SPA 路由(如 React Router / Vue Router)中,查询参数通常由
useSearchParams() 或 $route.query 自动管理,但底层依然是 URLSearchParams。
4.2 实现步骤与代码
4.2.1 手动拼接查询字符串(传统方式)
// 基础 URL
const baseUrl = 'https://api.example.com/search';
// 手动拼接
const query = '?q=JavaScript&page=1&limit=10';
const fullUrl = baseUrl + query;
注意:手工拼接极易忽略编码。若参数值包含
&、?、空格或中文,必须使用 encodeURIComponent() 对每个值进行编码。
const q = 'JS & TS';
const page = 1;
const safeQuery = '?q=' + encodeURIComponent(q) + '&page=' + page;
// 结果: ?q=JS%20%26%20TS&page=1
4.2.2 使用 URLSearchParams(推荐)
const params = new URLSearchParams();
params.append('q', 'JavaScript');
params.append('page', '1');
params.append('limit', '10');
const url = `/search?${params.toString()}`;
// 输出: /search?q=JavaScript&page=1&limit=10
URLSearchParams 自动对键和值进行百分号编码,无需手动处理。
4.2.3 多参数处理
同一个键允许出现多次(例如多选过滤)。URLSearchParams 原生支持重复键:
const params = new URLSearchParams();
params.append('tag', 'javascript');
params.append('tag', 'typescript');
params.append('tag', 'react');
console.log(params.toString());
// "tag=javascript&tag=typescript&tag=react"
// 获取所有 tag
console.log(params.getAll('tag'));
// ["javascript", "typescript", "react"]
4.2.4 可选参数处理
当参数存在时才添加到查询字符串中,避免出现 key=undefined 或空值:
function buildSearchUrl(base, { q, page, limit, sort }) {
const params = new URLSearchParams();
if (q) params.append('q', q);
if (page !== undefined) params.append('page', page);
if (limit !== undefined) params.append('limit', limit);
if (sort) params.append('sort', sort);
const queryString = params.toString();
return queryString ? `${base}?${queryString}` : base;
}
// 使用示例
console.log(buildSearchUrl('/search', { q: 'JS', page: 1 }));
// "/search?q=JS&page=1"
console.log(buildSearchUrl('/search', {}));
// "/search"
4.3 调试方法
- 浏览器 DevTools → Network 面板:查看请求 URL,确认查询字符串是否正确。
- 控制台打印
params.toString():验证编码结果。 - 使用
URL对象解析:
const url = new URL('https://example.com/search?q=hello&page=1');
console.log(url.searchParams.get('q')); // "hello"
console.log(url.searchParams.has('page')); // true
4.4 部署注意事项
| 注意事项 | 说明 |
|---|---|
| URL 长度限制 | 查询字符串通常限制在 2048~4096 字节(浏览器 / 服务器)。大量参数应使用 POST 请求体传递。 |
| 编码一致性 | 服务端与客户端需使用相同编码(通常 UTF-8)。前端 URLSearchParams 默认使用 UTF-8。 |
| 敏感数据 | 查询字符串会出现在浏览器历史、服务器日志中,切勿传递密码、 等敏感信息。 |
| 跨域 CORS | 查询参数本身不影响 CORS,但请求 URL 需在允许的原名单内。 |
4.5 常见错误与排查
- 忘记编码:参数值含
&导致解析错误 → 使用encodeURIComponent或URLSearchParams。 - 重复参数覆盖:手动拼接时误用
=而非&→ 使用append而非set。 - 可选参数判断不严谨:
if (page)当page=0时被跳过 → 应使用if (page !== undefined)。 - 空字符串保留:传
key=而非完全省略 → 使用if (val !== '')控制。
4.6 性能与稳定性优化
- 缓存参数序列化结果:对于固定参数(如分页),可缓存
params.toString()避免重复构建。 - 避免无效参数:构建前过滤掉
null、undefined、空字符串,缩短 URL 长度。 - 使用
URL对象代替手动拼接:更稳定,自动处理基路径与查询字符串的拼接。 - 批量操作时考虑
sort()方法:params.sort()可对参数键排序,提升缓存命中率。
// 性能优化示例:缓存序列化结果
const params = new URLSearchParams({ q: 'hello', page: 1 });
const cachedQuery = params.toString(); // 只计算一次
// 后续请求直接复用 cachedQuery
稳定性提示:在 Node.js 服务端解析查询字符串时,避免使用
querystring 旧模块,推荐使用 URLSearchParams(全局可用)或 new URL(url).searchParams。