跟你讲个真实经历。有次我接手一个老项目,页面里要读取 URL 上的筛选条件,代码里写的是 window.location.search.substring(1).split('&'),再循环 split('='),中间还得处理 decodeURIComponent 和空值判断。整个函数写了三十多行,看着就头大。后来我重构时全部换成了 URLSearchParams,一个 new URLSearchParams(location.search) 就搞定了。今天这篇就专门聊聊 URLSearchParams 获取参数这件事:它是什么、怎么用、实际项目里怎么落地、有哪些容易踩的坑。
这篇博文适合三类人看:刚学前端不久、还在用正则或 split 解析 URL 参数的新手;项目中遇到参数解析代码混乱、想找更优雅方案的中级开发者;以及在做代码走查时想说服同事统一用原生 API 的“操心型”选手。我会尽量把原理和实操揉在一起讲,读完你就能直接上手改造自己的代码。
1. URLSearchParams 到底是什么:从一次 URL 解析经历说起
先讲一个最简单的场景。你现在打开了一个页面,地址栏长这样:
code复制https://example.com/list?page=2&size=10&keyword=javascript
前端经常要做的事情是:从这段地址里把 page、size、keyword 取出来,用来发请求或者回显到 UI 上。在 URLSearchParams 出现之前,大家是怎么做的?最常见的就是我开头说的那种字符串拆分法。但真实业务哪有这么简单,参数顺序可能不同、值里可能带着 %E4%B8%AD%E6%96%87 这种编码、同一个 key 还可能出现两次,手写解析代码要考虑的边界情况多到让人崩溃。
URLSearchParams 就是浏览器原生提供的一个专门处理“URL 查询字符串”的工具。所谓查询字符串,就是 URL 中 ? 后面到 # 之前的那一段。它把 page=2&size=10&keyword=javascript 这种字符串解析成一个类似 Map 的结构,让你可以按 key 取值、遍历、增删改查。2016 年前后,各大浏览器基本都把它实现完整了,到今天已经是完全不依赖任何第三方库的前端基础能力。
讲个生活化类比:你手里拿着一串糖果(URL 里的参数),以前想吃草莓味得自己拆开糖纸挨个找,现在 URLSearchParams 相当于给你一个分好了格的糖盒,你只需要说“给我草莓味的”,它就能直接递给你。就这么简单。
1.1 三种常见的 URLSearchParams 构造方式
实际开发中,我用得最多的构造方式有三种,场景各不相同。
第一种,从当前页面 URL 的查询字符串构造:
javascript复制const params = new URLSearchParams(location.search);
location.search 拿到的就是 ?page=2&size=10 这一段,注意它自带开头的 ?,而 URLSearchParams 构造函数恰好能自动处理这个 ?,所以直接传进去是安全的,不需要手动 substring(1)。
第二种,自己传入一段字符串:
javascript复制const params = new URLSearchParams('name=张三&age=25');
这里有个细节值得注意:如果你传的字符串开头带 ? 也没关系,会被自动忽略;如果不带也能正常解析。两种写法都兼容,很贴心。
第三种,从完整 URL 里截取。严格来说这一步要用 URL 对象配合:
javascript复制const url = new URL('https://example.com/list?page=2&size=10');
const params = url.searchParams;
用 URL 对象拿到的 searchParams 也是一个 URLSearchParams 实例,而且它和 url.search 保持着一种“联动”关系:你改了 searchParams,再打印 url.toString() 会看到完整 URL 也跟着变了。这个特性在高阶用法里非常有用,后面实战部分我会细讲。
1.2 为什么我劝你放弃用 split 手写解析
有人可能觉得,手写解析也不是不行,何必多学一个 API?我做前端这些年,见过的真实翻车现场太多了。
第一坑:忘记 decodeURIComponent。URL 里的中文、空格、特殊符号会被浏览器编码成 %E5%BC%A0%E4%B8%89 这种形式,手写解析如果不做解码,拿出来的值直接展示在页面上就是乱码。URLSearchParams 内部会自动对 key 和 value 做 URI 解码,你拿到的直接就是人类能看懂的字符串。
第二坑:某个参数出现多次。比如 URL 是 ?tag=a&tag=b&tag=c,手写解析时如果用对象存储,后面会把前面的覆盖掉;但语义上可能是想把 a、b、c 都收集起来。URLSearchParams 提供 getAll('tag'),拿到的就是 ['a', 'b', 'c'],语义非常清晰。
第三坑:参数为空或格式不完整。像 ?a=1&&b=2 这种含空段的 URL,手写 split 可能会解析出一个空字符串的 key;?a 这种只有 key 没有 value 的情况,手写逻辑也得单独判断。URLSearchParams 对这些异常输入都有统一的容错策略,不会让你代码里到处是 if 判断。
说白了,手写解析不是不能做,但它把“解析细节”的复杂度暴露给了业务代码。用 URLSearchParams 是在用一个标准工具把这些脏活累活承接掉,代码可读性和健壮性都能上一个台阶。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. URLSearchParams 的完整方法图谱:不止是 get 参数
很多教程讲到 URLSearchParams 只讲 get 和 toString,其实它的 API 比想象中完整。我按使用频率和使用类型把它分成几组,每一组都给出可直接运行的示例。
2.1 读取参数的五个高频方法
假设页面上有这样一个 URL:
code复制https://example.com/products?keyword=手机&sort=price&sort=sales&page=1
我可以通过下面的代码读取全部信息:
javascript复制const params = new URLSearchParams(location.search);
// 1. get:取第一个匹配的值
const keyword = params.get('keyword'); // '手机'
// 2. getAll:取全部匹配的值
const sorts = params.getAll('sort'); // ['price', 'sales']
// 3. has:判断是否存在某参数
const hasPage = params.has('page'); // true
// 4. 遍历所有 key
for (const key of params.keys()) {
console.log(key); // 'keyword' 'sort' 'sort' 'page'
}
// 5. 遍历所有值
for (const value of params.values()) {
console.log(value); // '手机' 'price' 'sales' '1'
}
keys()、values()、entries() 这三个方法返回的都是迭代器,配合 for...of 使用非常顺手。其中 entries() 返回的是 [key, value] 的键值对数组迭代器,很多时候我会直接用它来把整个 URL 参数转成对象:
javascript复制const params = new URLSearchParams('name=张三&age=25');
const obj = Object.fromEntries(params);
// { name: '张三', age: '25' }
这里的 Object.fromEntries 是 ES2019 提供的方法,能把键值对列表转成对象。需要注意的是,如果 URL 里同一个 key 出现多次,转成对象后只会保留最后一个值。如果业务上需要保留全部值,要手动用 getAll 去处理。
2.2 增删改查:append、set、delete、sort
URLSearchParams 不仅能用来看,还能用来改。我在写“筛选条件联动”功能的场景里,经常会动态修改 URL 参数。
下面是它们的基本用法:
javascript复制const params = new URLSearchParams('page=1&size=10');
// append:追加一个参数,如果 key 已存在,不覆盖,而是并列保留
params.append('tag', '前端');
params.append('tag', 'JavaScript');
console.log(params.toString()); // 'page=1&size=10&tag=%E5%89%8D%E7%AB%AF&tag=JavaScript'
// set:设置参数,如果 key 已存在则替换为最新值,并删除旧的多余值
params.set('page', '2');
console.log(params.toString()); // 'page=2&size=10&tag=%E5%89%8D%E7%AB%AF&tag=JavaScript'
// delete:删除参数
params.delete('size');
console.log(params.toString()); // 'page=2&tag=%E5%89%8D%E7%AB%AF&tag=JavaScript'
// sort:按 key 的 Unicode 码点排序
params.sort();
console.log(params.toString()); // 'page=2&tag=%E5%89%8D%E7%AB%AF&tag=JavaScript'
这里我特别想提醒 append 和 set 的区别:append 永远追加,不关心是否已有同名的 key;set 则会“清掉旧的,只留新的”。实际开发中,如果你要实现“更新 URL 中的某个参数”这个动作,应该用 set 而不是 append,否则参数会越加越多。
2.3 序列化与边界行为:toString 和字符串输出
URLSearchParams 实例可以直接调用 toString() 输出格式化后的查询字符串。这个过程中有几个自动行为需要注意。
自动进行 URI 编码。看下面的例子:
javascript复制const params = new URLSearchParams();
params.set('keyword', 'Javascript 教程');
params.append('from', 'a&b=c');
console.log(params.toString());
// 'keyword=Javascript+%E6%95%99%E7%A8%8B&from=a%26b%3Dc'
可以看到,空格会被编码成 +,中文会被 encodeURIComponent 编码,& 和 = 这些特殊字符也会被转义。所以当你用 toString() 拼接 URL 时,不用再额外做一次编码,直接拼到 ? 后面即可。
另外一个容易被忽略的点是:URLSearchParams 内部并不维护“hash”。换句话说,它只关注 ? 到 # 之间的部分。如果你构造参数时传入了 #,它会把 # 之后的内容当成 value 的一部分。比如:
javascript复制const params = new URLSearchParams('a=1#section');
console.log(params.get('a')); // '1#section'
所以在处理完整 URL 时,正确的做法是先把它拆成 URL 对象,再用 url.searchParams,而不要直接把带 # 的字符串丢给 URLSearchParams。
3. 实战:从 URL 取参的三种正确姿势,你选哪个
前面把 API 讲了一遍,现在到真正落地环节。这个部分我会以“从 URL 取参数”为主线,给出三种我实际项目里验证过的姿势,以及它们分别适合什么场景。
3.1 姿势一:从 location.search 直接解析当前页面参数
这是最基础、最常用的场景。页面加载后,前端要读取地址栏中的参数来初始化数据。
javascript复制// 页面 URL 类似:https://example.com/detail?id=10086&from=share
const params = new URLSearchParams(location.search);
const id = params.get('id'); // '10086'
const from = params.get('from'); // 'share'
在 Vue 或 React 的组件里,我一般会封装一个工具函数,避免每个组件里重复写:
javascript复制// utils/url.js
export function getQueryParam(key) {
return new URLSearchParams(window.location.search).get(key) || '';
}
用的时候:
javascript复制import { getQueryParam } from '../utils/url';
const id = getQueryParam('id');
这里有个小细节:get 方法如果找不到 key 返回的是 null,所以我在封装时统一用 || '' 转成空字符串,这样调用方不需要每次都判空。
3.2 姿势二:用 new URL() 解析完整链接,更稳健
有时候我们拿到的不是 location.search,而是一个完整的 URL 字符串。比如从外部系统跳转过来时带了一个链接,或者是后端在配置项里下发了一个带参数的回调地址。这时候直接用 location.search 就不行了,推荐用 new URL()。
javascript复制const fullUrl = 'https://example.com/path?name=Tom&age=18#/home';
const url = new URL(fullUrl);
const params = url.searchParams;
const name = params.get('name'); // 'Tom'
const age = params.get('age'); // '18'
这里 new URL() 会自动帮你把 https://example.com/path?name=Tom&age=18#/home 拆分成 origin、pathname、search、hash 等部分,searchParams 拿到的是不包含 # 干扰的干净查询参数。这是相比“直接 new URLSearchParams(fullUrl)”更稳健的地方。
在 Node.js 中需要解析 URL 的完整链接时(比如后端服务里校验回调地址),同样可以用这段逻辑,因为 Node.js 从 v10 开始已经默认内置了 URL 和 URLSearchParams 的全局实现:
javascript复制// Node.js 环境
const url = new URL('https://example.com/api?userId=123');
const userId = url.searchParams.get('userId'); // '123'
3.3 姿势三:处理带 hash 路由的 URL,别让 # 前方“乱入”
现在很多单页应用用的是 hash 路由,URL 长这样:
code复制https://example.com/index.html#/detail?id=10086
注意,这里的 id=10086 是在 # 后面的,它并不是传统意义上的“查询字符串”,而是 hash 路由内部的参数。此时如果用 location.search 获取,拿到的是空字符串;用 new URLSearchParams(location.search) 取 id,也只能取到 null。这其实是很多新手困惑的点:为什么我用 URLSearchParams 明明没问题,但取到的参数却是空的?
解决这个问题的标准做法是:从 location.hash 里取出路由部分,再解析其中的查询字符串:
javascript复制// hash 示例:'#/detail?id=10086'
const hash = location.hash; // '#/detail?id=10086'
const hashPath = hash.replace(/^#/, ''); // '/detail?id=10086'
// 方法一:字符串截取
const queryString = hashPath.split('?')[1] || ''; // 'id=10086'
const params = new URLSearchParams(queryString);
const id = params.get('id'); // '10086'
// 方法二:用 URL 对象解析(更严谨)
const url = new URL(hash, window.location.origin);
const idByUrl = url.searchParams.get('id'); // '10086'
第二种写法里,new URL(hash, window.location.origin) 的意思是“以当前站点为基准,把 #/detail?id=10086 解析成完整 URL”。因为 hash 开头的 # 在 URL 标准中表示 fragment,所以当你把它传进 URL 构造函数时,浏览器会把 ?id=10086 放在 hash 内部,再通过 url.searchParams 取到的是 10086。实测下来这个方案在大多数现代浏览器中都有效,代码还更简洁。
3.4 扩展实战:用 URLSearchParams 拼接和更新筛选参数
除了“读取”参数,日常开发里“生成带参数 URL”的需求也很多。比如一个商品列表页,用户选了分类、排序方式和页码,需要把筛选状态同步到 URL,让用户刷新后还能保持筛选条件。
我以前的做法是写一堆字符串拼接,后来改成用 URLSearchParams 统一管理,代码直观了很多:
javascript复制// 初始筛选参数
const params = new URLSearchParams();
params.set('page', '1');
params.set('size', '20');
params.set('category', 'phone');
params.set('sort', 'price');
// 用户切换排序后,更新参数
params.set('sort', 'sales');
// 跳转到新 URL
const newUrl = `/list?${params.toString()}`;
window.location.href = newUrl;
如果要更新当前页面的 URL 但不刷新页面,可以配合 history.replaceState 实现:
javascript复制const params = new URLSearchParams(location.search);
params.set('page', '3');
// 不刷新页面,只替换地址栏
history.replaceState(null, '', `${location.pathname}?${params.toString()}`);
这段逻辑在实现“列表筛选 + 浏览器前进后退”的联动场景时非常实用。你只需要监听 popstate 事件,再从 location.search 中读取参数、刷新列表数据即可。
4. 常见问题与排查实录:我在项目中踩过的坑
这章是实打实的经验之谈。以下问题都是我在实际开发或者帮同事排查代码时真实遇到过的,基本覆盖了使用 URLSearchParams 最容易翻车的几个点。
4.1 为什么我拿到的中文参数是一串 %E4%BD%A0%E5%A5%BD?
这种情况几乎每个前端都遇到过。URL 里看到一个参数值是 %E4%BD%A0%E5%A5%BD,页面里打印出来也是这串“天书”。原因很简单:浏览器地址栏展示的是编码后的字符串,而 URL 标准允许查询字符串中出现的合法字符有限,中文、空格、&、= 等都会被编码。
如果你用 URLSearchParams 读取,它会在底层自动做解码。所以正常情况下你拿到的应该是“你好”。如果你打印出来还是编码后的字符串,那大概率是拿错了对象。比如你把 location.search 直接打印出来看,它自然是编码形态;你需要先 new URLSearchParams(location.search) 再 .get()。
如果你在 Node.js 或某些服务端环境手动拼 URL,想让中文不被编码,可以使用 encodeURIComponent 预编码,也可以直接用 URLSearchParams.toString() 帮你去编码。我个人建议的做法是:能用 URLSearchParams 生成查询串就不要自己手写中文拼接,这样格式一定是对的。
4.2 同一个 key 出现了多次,get 为什么只返回第一个?
这是 URLSearchParams 一个让很多人疑惑的行为。比如 URL 是 ?tag=a&tag=b&tag=c,你执行 params.get('tag'),只会得到 'a'。这是符合规范的设计——get 语义上就是“取第一个”。
如果你确实需要把所有值都取出来,请使用 getAll。举例来说,做一个多标签筛选功能时,URL 可能长这样:
javascript复制const params = new URLSearchParams('tag=前端&tag=Node.js&tag=JavaScript');
const tags = params.getAll('tag');
// ['前端', 'Node.js', 'JavaScript']
还有一个容易踩的点是:用 Object.fromEntries(params) 转对象时,重复的 key 也会丢失前面的值,只保留最后一个。这不算 bug,而是 API 设计的取舍。建议在选取方案之前,先想清楚你的业务里有没有“一 key 多值”的情况。
4.3 URLSearchParams 可以直接 forEach 吗?
可以,但要注意回调参数的顺序。URLSearchParams 实现了 forEach 方法,但回调参数顺序是 (value, key),而不是像 Map、Object.entries 那样 (value, key) 还是 (key, value) 会让你搞混。
看下面的例子:
javascript复制const params = new URLSearchParams('name=Tom&age=18');
params.forEach((value, key) => {
console.log(`${key}: ${value}`);
});
// 输出:
// name: Tom
// age: 18
没错,第一参数是 value,第二参数是 key。这跟数组的 forEach((item, index)) 的直觉完全不一样,写惯了的人也会偶尔卡壳。如果觉得容易记混,我建议直接用 for...of + entries():
javascript复制for (const [key, value] of params.entries()) {
console.log(`${key}: ${value}`);
}
这行代码的可读性比 forEach 更直观,而且不会出现顺序记反的问题。
4.4 在 Node.js 环境中能用吗?
答案是可以,而且从 Node.js v10 开始 URLSearchParams 就是全局对象了,不需要 require 任何模块。不过 Node.js 版本的实现和浏览器版在绝大多数行为上保持一致,但仍有一个小差异要留意:Node.js 的 URLSearchParams.toString() 对空格编码使用 +,这与 querystring 模块的行为一致,而如果你用 encodeURIComponent 手动编码,空格会被编码成 %20。这两者在大部分后端框架都能正确解码,但如果你在签名校验场景中比较两个字符串是否一致,就很容易发现对不上的情况。建议后端同学在对比签名时统一使用同一个编码方式。
在 Node.js 中解析带 query 的完整 URL 时,最稳妥的方式还是配合 URL 对象:
javascript复制const url = new URL('https://example.com/api?name=张三');
console.log(url.searchParams.get('name')); // '张三'
4.5 从服务器获取共享列表失败: 无效的参数,这是什么问题?
有段时间我负责排查一个接口报错,错误信息是“从服务器获取共享列表失败: 无效的参数”。乍一看是后端报的错,但我们查了很久发现根因其实在前端:某个链路里我用 URLSearchParams 把参数序列化后拼到 URL 上,但拼接时没有把 # 放在最后,导致后端拿到的 query 参数缺了一块。
具体问题是这样:当时页面的 URL 结构是 https://example.com/list?page=1#/detail?id=2,我取 URLSearchParams(location.search) 读 id,一直取不到值,再往下游传参时就带了个空值过去,服务端校验没过,抛出了“无效的参数”。后来我把这一行的解析改成用 new URL(location.href) 方式,才正确读取了 hash 内的参数。
这类问题的排查思路其实很固定:先确认你解析的是 search 还是 hash;再确认参数有没有被编码/解码;最后确认同一个 key 是不是有多个值。前端的 URL 参数问题,80% 都能归到这三点上。
5. 延伸:URLSearchParams 与手写解析、第三方库的对比与选型
写到这里,我相信你已经能熟练使用 URLSearchParams 了。但在真实项目中还会遇到一类问题:到底要不要引第三方库?什么时候引,什么时候用原生就够?我把我的判断标准分享出来。
5.1 手写 split 解析 vs URLSearchParams,差距在哪
前几年网上流传的各种“一行代码解析 URL 参数”方案,很多是这样的:
javascript复制function getParam(name) {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
const r = window.location.search.substr(1).match(reg);
if (r !== null) return decodeURIComponent(r[2]);
return null;
}
这段代码在简单场景下能跑,但问题很明显:正则写错一个字符就完蛋,遇到 +(空格)要单独做替换,遇到同名参数拿不到全部结果,不同浏览器对编码的处理还不尽相同。用 URLSearchParams 可以完全规避这些正则地狱。
还有人为了“兼容老浏览器”在手写 polyfill,其实现在主流浏览器对 URLSearchParams 的支持已经非常成熟。如果你要兼容 IE 或者一些极老版本,也可以引入 url-search-params-polyfill 这种轻量包,但这类需求已经越来越少了。
5.2 什么时候才需要用 qs 或 query-string 库
URLSearchParams 是标准库,但标准库不是万能的。它有两个明显的短板:一是默认把所有值都当字符串处理,没有类型转换;二是复杂嵌套对象能力缺失。比如:
javascript复制// 后端接口需要这种嵌套结构
{
filters: {
category: 'phone',
price: { min: 100, max: 5000 }
},
page: 1
}
这种结构用 URLSearchParams 根本无法直接表达。如果你使用的后端接口必须接收这种嵌套 query,就得考虑用 qs 或 query-string 这类库。qs 的序列化能力很强,支持数组和嵌套对象,常见写法如下:
javascript复制import qs from 'qs';
const obj = {
filters: { category: 'phone', price: { min: 100, max: 5000 } },
page: 1
};
const queryString = qs.stringify(obj);
// 'filters%5Bcategory%5D=phone&filters%5Bprice%5D%5Bmin%5D=100&filters%5Bprice%5D%5Bmax%5D=5000&page=1'
不过我要提醒一句:能不用嵌套结构就尽量不用。很多接口之所以设计成嵌套 query,往往是历史遗留问题。在前端代码里,为了一个嵌套对象引入一个几十 KB 的库,性价比并不高。我的原则是:如果只是简单参数,一律用原生 URLSearchParams;只有确认后端接口强依赖嵌套参数或数组序列化时,才上第三方库。
5.3 和 axios 参数序列化配合的经验
axios 发 GET 请求时,params 会自动序列化并拼到 URL 后面。默认序列化器处理数组的方式是 a[]=1&a[]=2 这种,有时候后端不认。这时候你可以手动指定序列化函数,用 URLSearchParams 来控制:
javascript复制import axios from 'axios';
axios.get('/api/list', {
params: {
page: 1,
size: 20,
tag: ['前端', 'Node.js']
},
paramsSerializer: (params) => {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach((item) => searchParams.append(key, item));
} else {
searchParams.append(key, value);
}
});
return searchParams.toString();
}
});
这样最终发出的 URL 是 ?page=1&size=20&tag=%E5%89%8D%E7%AB%AF&tag=Node.js,后端按 tag 数组去接就能接住。这里我用到的就是 URLSearchParams 的 append,确保同名参数不会被覆盖,而是并列出现。实际联调中,这种写法对 Rails、Spring 等后端框架都很友好,基本不会出现数组解析问题。
6. 调试技巧和工具链搭配
写完代码不是终点,调试好了才算完。分享几个我平时排查 URL 参数问题时使用的高效手段。
浏览器 DevTools 的 Console 面板可以直接执行 JS。当你不太确定某个 URL 上的参数怎么解析时,直接在 Console 里敲:
javascript复制new URLSearchParams(location.search).get('page')
回车就能看到结果,根本不用修改源码。这是排查线上问题最快的方式。
Network 面板里查看请求 URL 也是常用的调试手段。打开页面,发一个请求,在 Network 里找到这条记录,点开 Payload 或 Query String Parameters,就能看到前端实际发出的参数名称和值。如果发现参数多了一个空字符串或者乱码,基本可以判断 URLSearchParams 序列化或编码环节出了问题。
如果你在处理超长 URL 或者需要生成签名链接,我建议在本地写一个简单的 Node 脚本验证一下编码结果:
javascript复制// test.mjs
const params = new URLSearchParams();
params.set('name', '张三');
params.set('tags', 'a b c');
console.log(params.toString());
// 输出:name=%E5%BC%A0%E4%B8%89&tags=a+b+c
用 Node 跑一下,输出结果一目了然。等到真正去浏览器里验证时,就能减少很多“为什么和想象不一样”的困惑。
7. 最后分享一个小技巧:用 URLSearchParams 简化 iframe 传参
文章快结束了,再送一个我在实际项目里常用的小技巧。如果你在做 iframe 嵌入页面,父页面要往子页面传参,经常要拼这种 URL:
javascript复制const url = `https://iframe.example.com/embed?id=${id}&token=${token}`;
直接用模板字符串拼接很容易出错,尤其是 token 这种可能含有 & 或 = 的字符串。正确的做法是用 URLSearchParams 生成,稳妥得多:
javascript复制const params = new URLSearchParams();
params.set('id', id);
params.set('token', token);
const iframeUrl = `https://iframe.example.com/embed?${params.toString()}`;
frame.src = iframeUrl;
同理,如果你要在 iframe 内部读取父页面传进来的参数:
javascript复制const params = new URLSearchParams(location.search);
const token = params.get('token');
这一套组合用下来,参数传递基本不会出幺蛾子。我在实际开发中,曾经因为 token 里带了个 + 号导致后端解密失败,排查了大半天才找到根因。自从统一改用 URLSearchParams 之后,这类问题就再也没出现过了。这就是从“会用到”到“用好”的区别。
