前端同事在页面里用 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 各管一段,取之前先看清问号在哪。