浏览器地址栏里的问号后面,藏着整个网页的状态。你分享一个商品链接,朋友点开却看不到你选好的尺码——多半是参数没传对。JS里拿这些参数,方法不止一种,但最顺手的永远是那三五行代码。
先看最实在的写法:const params = new URLSearchParams(window.location.search)。这一行就把问号后面的东西全拆成了键值对。想拿某个值?params.get('id')直接返回字符串。没有这个参数就返回null,判断起来也干脆。这个方法支持has()检查是否存在,getAll()取重复参数的所有值,forEach()遍历全部参数。Chrome、Firefox、Safari这些主流浏览器从2016年起就原生支持,兼容性根本不是问题。
但有个坑得提醒你——URLSearchParams会把+号解码成空格。如果你传的是Base64编码的内容,或者带+号的搜索词,取出来就变了样。我遇到过两次这种问题,一次是传加密串,一次是传时间戳。解决也简单,用decodeURIComponent包一层手动处理,或者干脆在编码端用encodeURIComponent把+转成%2B。
老项目里还能见到另一种写法——正则匹配。比如location.search.match(/[?&]id=([^&]*)/),取第一个捕获组就是值。这法子十年前是主流,现在看纯粹是给自己找麻烦。如果参数顺序变了,或者值里恰好包含&字符,正则就崩了。除非你要兼容IE8那种古董浏览器,否则别碰正则。
还有一类特殊场景——hash路由。单页应用里参数常放在#后面,比如example.com/#/product?id=123。这时候window.location.search是空的,得改用window.location.hash。先取hash部分,再手动去掉开头的#,然后用URLSearchParams解析。注意hash里可能还嵌套路由路径,得先按?切一刀,只取问号后面的部分。
实际开发中更推荐封装个小工具函数。别每次都用URLSearchParams直接操作,因为你需要处理null、默认值、类型转换。比如getParam('page', 1),参数不存在时返回数字1,存在但传了"abc"时要返回NaN。这种逻辑散落在各处,代码很快就臭了。集中写一个utils/query.js,导出getParam(name, defaultVal)和setParam(name, value),全局复用。setParam那边要保留原有参数,只改其中一个,再推回history。
最后说个冷门细节——URLSearchParams的迭代顺序就是参数在URL里的出现顺序。如果你需要按顺序处理多个同名参数,直接用for (const [key, value] of params)遍历就行。但要注意,URLSearchParams构造函数如果传完整URL会报错,它只接受query string部分。所以别偷懒,务必先split('?')[1]再传参。
写代码时多留个心眼:参数值永远别直接塞进DOM或SQL里,XSS和注入攻击最爱走这条路。拿到值先做校验,白名单、正则、转义,三选一。有些框架自带过滤,但原生JS环境全靠自己把关。
核心其实就一句话——URLSearchParams是正解,封装函数是习惯,警惕特殊字符是底线。其他的,等你真遇到需求再深入也不迟。
