前端同事在页面里用 location.search 取渠道号,本地测得好好的,上线后拿到的全是空字符串。他把地址贴给我,链接是带井号的那种。

井号后面的部分归 hash 管,search 只认问号开始的那一段。

它返回的是什么

location.search 返回从问号开始到井号之前的完整字符串,包括问号本身。地址是 a.html?from=wx&id=3 时,返回 ?from=wx&id=3。空参数时返回空串,不是 null,判断时别写错。

解析的稳妥写法

  • 用 URLSearchParams,const p = new URLSearchParams(location.search)
  • 取值的 get 方法,没这个键返回 null,给默认值要写或运算
  • 老项目不支持时,手写 split 加 decodeURIComponent

编码问题最容易被忽略

中文参数经过浏览器会自动编码,取出来要 decodeURIComponent 一次,不然拿到的是百分号加十六进制。加号在查询串里代表空格,直接 decode 会把加号变空格,需要先替换成百分号加 2B。哈希路由的项目,参数往往在 hash 里,得从 location.hash 里切。

和 hash 的边界

地址 a.html?x=1#/list?y=2 里,search 是问号到井号那一段,后面的问号属于 hash。用井号做路由的单页应用,页面内的参数只能自己解析 hash,别指望 search。

上线后取不到的其他原因

链接被短链服务重写过,参数丢了;跳转时用了 302,查询串没带过去;页面在 iframe 里,读到的是 iframe 自己的地址。打开控制台打印 location.href 对一遍,比盯着代码猜快。

同事那条链接的参数确实在井号后面,改成从 hash 解析就通了。search 和 hash 各管一段,取之前先看清问号在哪。