本文要点
get 按参数名取值,但只返回第一个匹配的值
getAll 按参数名取出全部值,返回一个数组
has 返回布尔值,回答的是“这个键在不在”,不关心它有几个值、值是什么

本文目录
先分清:查询串是文本,URLSearchParams 是能查键值的对象
如果你手里有一段查询串,比如 q=URLUtils.searchParams&topic=api,想按参数名取值,直接对字符串做切片很容易出错。URLSearchParams 就是为这件事准备的接口,它把查询串解析成一组键值对,并提供按名取值的方法。
构造方式有两种常见写法。第一种直接传查询串文本,开头带不带问号都可以,带问号时会被去掉。第二种传一个普通对象,对象的每个属性会变成一组参数。
下面全部是内存里的自建示例,不读取任何真实网址,也不涉及带 Token 的地址。你可以在浏览器的控制台里逐段粘贴运行,观察输出。
const paramsString = "q=URLUtils.searchParams&topic=api";
const searchParams = new URLSearchParams(paramsString);
console.log(searchParams.toString());
// "q=URLUtils.searchParams&topic=api"一个前提:URLSearchParams 构造函数不解析完整 URL。如果你把整条网址传进去,它不会自动帮你截出问号后面的部分,而是把整条字符串当成查询串来处理。要处理完整网址,应先取到它的 search 部分再交给构造函数。
get 只返回第一个值,重复键不会全部给你
get 按参数名取值,但只返回第一个匹配的值。这是最容易被忽略的一点:同一个键出现多次时,get 不会把它们合并,也不会报错,它只给你排在最前面的那一个。
const paramStr = "foo=bar&foo=baz";
const searchParams = new URLSearchParams(paramStr);
console.log(searchParams.get("foo"));
// "bar",仅返回第一个值如果键不存在,get 返回 null,而不是空字符串。这个区别在写判断时很重要:null 说明“没有这个参数”,空字符串说明“有这个参数但值是空的”。
console.log(searchParams.get("missing"));
// null所以当你确定某个参数只会出现一次时,用 get 最直接;一旦这个参数可能重复出现,就该换 getAll。
getAll 返回数组,多值参数要看它
getAll 按参数名取出全部值,返回一个数组。同一个键出现几次,数组里就有几个元素,顺序和它们在查询串里出现的顺序一致。
const paramStr = "foo=bar&foo=baz";
const searchParams = new URLSearchParams(paramStr);
console.log(searchParams.getAll("foo"));
// ["bar", "baz"]只有一个值时,getAll 返回的是只含一个元素的数组,不是那个值本身。这一点和 get 的输出形态不同,写代码时不要混用。
const single = new URLSearchParams("topic=api");
console.log(single.getAll("topic"));
// ["api"]
console.log(single.get("topic"));
// "api"键不存在时,getAll 返回空数组。判断“有没有值”可以用数组长度,而不是判断它是不是 null。
has 判断键在不在,别拿 get 的返回值去猜
has 返回布尔值,回答的是“这个键在不在”,不关心它有几个值、值是什么。
const searchParams = new URLSearchParams("q=URLUtils.searchParams&topic=api");
console.log(searchParams.has("topic"));
// true
console.log(searchParams.has("missing"));
// false为什么不用 get 的返回值来判断存在性?因为空值参数会让这个判断失效。URLSearchParams 不区分“等号后面什么都没有”和“完全没有等号”这两种写法,两者取出来都是空字符串。
const emptyVal = new URLSearchParams("foo=&bar=baz");
console.log(emptyVal.get("foo"));
// ''
const noEquals = new URLSearchParams("foo&bar=baz");
console.log(noEquals.get("foo"));
// 也返回 ''
console.log(noEquals.toString());
// 'foo=&bar=baz'也就是说,get 返回空字符串时,你分不清是“参数存在但为空”还是“参数根本不存在”。要回答存在性,用 has;要回答值是什么,用 get 或 getAll。
toString 把参数拼回查询串,注意加号会被当空格
toString 返回由当前参数组成的字符串,可以直接接在网址后面使用。它输出的内容不含开头的问号。
const paramsObj = { foo: "bar", baz: "bar" };
const searchParams = new URLSearchParams(paramsObj);
console.log(searchParams.toString());
// "foo=bar&baz=bar"这里有一个容易踩的坑:构造函数会把加号解释为空格。如果参数值里本来含有加号,读出来就会变成空格。
const searchParams2 = new URLSearchParams("bin=E+AXQB+A");
console.log(searchParams2.get("bin"));
// "E AXQB A",加号被替换为空格要避免这个问题,可以在写入前用 encodeURIComponent 对值做编码,读出来时再解码。这样加号会以转义形式保存,不会被当成空格。
const encoded = encodeURIComponent("E+AXQB+A");
const searchParams3 = new URLSearchParams("bin=" + encoded);
console.log(searchParams3.get("bin"));
// "E+AXQB+A"另外,toString 的输出顺序就是参数在对象里的排列顺序,它不会自动帮你排序。需要固定顺序时,要自己控制写入的先后。
一份自建练习:从构造到读值走一遍
把上面几个方法串起来,用一段自建查询串走一遍完整流程。所有内容都在内存里,不发送请求,也不读写文件。
const raw = "tag=tea&tag=cup&empty=&flag";
const sp = new URLSearchParams(raw);
console.log(sp.has("tag")); // true
console.log(sp.get("tag")); // "tea",只取第一个
console.log(sp.getAll("tag")); // ["tea", "cup"]
console.log(sp.has("empty")); // true
console.log(sp.get("empty")); // ''
console.log(sp.has("flag")); // true,无等号也算存在
console.log(sp.get("missing")); // null
console.log(sp.toString()); // "tag=tea&tag=cup&empty=&flag="对照输出可以确认三件事:重复键用 getAll 才能拿全;空值参数用 has 判断存在、用 get 取值会得到空字符串;没有等号的参数在 toString 里会被补上等号。
检查结果时,建议把每一步的输出单独打印出来核对,而不是只看最后一行 toString。因为 toString 会把空值和补等号的处理一起呈现,单看它不容易发现前面哪一步取值取错了。
什么时候不该用这套方法
URLSearchParams 处理的是查询串本身,它不负责解析完整网址,也不负责发请求。如果你的输入是整条网址,先取它的 search 部分再构造,否则整条字符串会被当成一个键。
它也不适合用来处理需要保留原始字节的二进制数据。加号被当空格这一点,会让某些编码结果在往返过程中发生变化,这类场景应先用 encodeURIComponent 编码。
本文只讲 get、getAll、has、toString 四个方法在内存示例上的行为,不涉及真实含 Token 的网址,也不涉及网络请求、存储或跨域问题。动手练习时请使用自己构造的示例字符串,不要拿生产环境里的真实查询串直接试。
观看知识要点视频 18 秒
18秒无旁白要点导览,文字来自已审核正文;完整步骤、条件及参考资料见下方。
参考资料
以下原始资料提供本文依据;请结合日期、适用条件和产品说明查阅。
请结合原始资料的适用条件阅读。
返回浏览器工具 →