第 4 课
查询字符串与参数
正确构造与解析 `?key=value&` 参数对。
在常见的 https:// URL 中,第一个 ? 之后 到 #(若有)之前 的整段字符称为 query(查询)部件。多数浏览器与服务器框架会把它按类似 application/x-www-form-urlencoded 的规则拆成 键值对——即便来源不是 HTML 表单。
https://api.example.com/items?tag=book&sort=price_asc&page=2
解析后通常得到 tag、sort、page 三个键。
键值对写法
- 多个键值对用
&连接(陈旧实现里偶有;,除非明确兼容否则不要自创)。 - 单个键值对里,第一个出现的
=划分名称与取值:flag→ 许多解析器解释为「取值是空字符串」q=→ 显式空值q=ruby+gems→ 在表单规则里+可能代表空格(见第 5 课)
?q=hello&empty=&flag
标准允许 重复的键名:
?tag=a&tag=b
最终是当作数组、Set、还是后者覆盖前者,由各框架自定——接入他人 API 前应阅读文档或抓包核对。
拼接前先编码取值
取值里若可能出现 &、=、# 或非 ASCII,应先对每个 取值(以及必要时键名) 做恰当的组件级编码再拼接:
const base = "https://example.com/search";
const params = new URLSearchParams({ q: "fish & chips", city: "São Paulo" });
const url = `${base}?${params.toString()}`;
使用 URL 对象可避免手工维护 ?/& 边界:
const url = new URL("https://example.com/search");
url.searchParams.set("q", "100% completion");
console.log(url.toString());
解析时的常见翻车点
若在 部分解码之后 用简单的 split('&'):
decodeURIComponent('a=b%26c=d')
当 %26 变成字面 &,朴素拆分就会把一对键值错误拆成两对。更安全的是 URL、URLSearchParams、服务端成熟库——它们按字节状态机遍历,或在规范化后再拆分。
相对 URL 与 HTML 上下文
在 <a href="?page=2"> 这类相对链接里,浏览器会相对于 当前文档的基准 URL 进行解析——结果未必是你直觉中的「站内根路径」,要理解 RFC 3986 的 相对解析 规则。
顺序与规范化
签名、CDN 缓存键、去重比对等场景往往会规定 参数的规范顺序与编码写法(OAuth 1.0 的签名串、x-www-form-urlencoded 与纯 query 的差别等都与「如何把若干键值转成唯一字节串」有关)。不要随意依赖「对象遍历顺序看起来像插入顺序」这种偶然行为。
掌握好查询字符串,本质仍是:哪里是结构分界、每层期望的是原始文本还是百分号字节——再配合下一课里的 + 规则即可覆盖大多数工程问题。