Node.js:拼 URL 查询参数,`URLSearchParams` 比手写字符串稳一点

28 次浏览4 条回复

写小脚本调接口时,经常要拼 ?page=1&keyword=...。参数一多,手写字符串很容易漏掉转义,Node 里直接用 URLSearchParams 会省心些。

环境:Node.js 18+。保存成 query-demo.mjs

const params = new URLSearchParams({
  keyword: 'hello world',
  page: '1',
  debug: 'true',
})

params.append('tag', 'nodejs')
params.append('tag', 'stdlib')

const url = `https://example.com/search?${params.toString()}`
console.log(url)
console.log(params.getAll('tag'))

跑一下:

node query-demo.mjs

输出里的空格会被正常编码,重复的 tag 也能保留下来。

这种适合本地脚本、测试请求、简单 webhook。要是参数里有数字或布尔值,我一般会先显式转成字符串,别让隐式转换藏得太深。

还有个小坑:如果参数值可能是数组,最好统一走 append,别直接塞进对象里。比如 new URLSearchParams({ tag: ['a', 'b'] }) 最后会变成一个字符串,不是两个 tag

我一般会写成:

for (const tag of tags) {
  params.append('tag', tag)
}

这样后端按重复 query key 接收时比较稳。

补一个容易忽略的点:URLSearchParams 会把空格编码成 +,不是 %20。大多数后端解析 query 都没问题,但如果对方接口签名是按原始字符串算的,最好先确认它期待哪种编码方式。

普通请求里用它很省事;一旦牵涉签名、缓存 key 这种严格比较,就别只看“能请求成功”了。

还有一种场景也挺适合:base URL 本身可能已经带 query 时,可以先 new 一个 URL,再改它的 searchParams,不容易把 ?& 拼乱。

const url = new URL('https://example.com/search?from=home')
url.searchParams.set('keyword', 'hello world')
url.searchParams.append('tag', 'nodejs')

console.log(url.toString())

set 会覆盖同名参数,append 会保留重复 key,这两个分清楚基本就够用了。

如果后面还想把参数转回对象,也要小心重复 key 会丢信息。

const params = new URLSearchParams('tag=nodejs&tag=stdlib&page=1')

console.log(Object.fromEntries(params))
console.log(params.getAll('tag'))

第一个只会留下最后一个 tag,所以遇到筛选条件、标签这种多值参数,还是用 getAll 明确取比较稳。