如何让URLSearchParams正确处理参数中的&符号?
解决URLSearchParams误解析参数值中&的问题
问题场景
从非技术用户填写的表单中获取的字符串分两种情况:
- 单个值,比如
Temparate Grasslands, Savannas & Shrublands - 多参数查询串,比如
biome=Temparate Grasslands, Savannas & Shrublands&eco_region=grasslands
直接用URLSearchParams解析时,会把参数值里的&误判为参数分隔符,导致解析结果错误:
> s = 'biome=Temparate Grasslands, Savannas & Shrublands&eco_region=grasslands' 'biome=Temparate Grasslands, Savannas & Shrublands&eco_region=grasslands' > p = new URLSearchParams(s) URLSearchParams { 'biome' => 'Temparate Grasslands, Savannas ', ' Shrublands' => '', 'eco_region' => 'grasslands' }
预期解析结果:
URLSearchParams { 'biome' => 'Temparate Grasslands, Savannas & Shrublands', 'eco_region' => 'grasslands' }
解决方案
核心逻辑是区分参数分隔符的&和参数值内的&:参数分隔符的&必然紧跟在参数值后,且后面是key=结构。基于这个特性,用正则拆分出正确的key=value片段,再处理参数值内的&。
方法一:修复字符串后解析
const rawStr = 'biome=Temparate Grasslands, Savannas & Shrublands&eco_region=grasslands'; // 按参数分隔符&(后接key=结构)拆分字符串 const paramParts = rawStr.split(/&(?=[a-zA-Z_]+=)/); // 将每个片段内的&替换为URL编码的%26,再拼接成合法查询串 const fixedQueryStr = paramParts.map(part => part.replace(/&/g, '%26')).join('&'); // 解析修复后的字符串 const params = new URLSearchParams(fixedQueryStr); console.log(params.get('biome')); // Temparate Grasslands, Savannas & Shrublands console.log(params.get('eco_region')); // grasslands
方法二:手动构建URLSearchParams
如果不想修改原始字符串,可拆分后逐个添加参数:
const rawStr = 'biome=Temparate Grasslands, Savannas & Shrublands&eco_region=grasslands'; const params = new URLSearchParams(); // 拆分出所有key=value片段 const paramParts = rawStr.split(/&(?=[a-zA-Z_]+=)/); paramParts.forEach(part => { // 拆分key和value(兼容value中包含=的情况) const [key, ...valueSegments] = part.split('='); const value = valueSegments.join('='); // 添加参数,URLSearchParams会自动处理编码 params.append(key, value); }); console.log(params.get('biome')); // Temparate Grasslands, Savannas & Shrublands console.log(params.get('eco_region')); // grasslands
兼容单个值场景
如果输入是无key=结构的单个值,上述方法依然有效:
const rawStr = 'Temparate Grasslands, Savannas & Shrublands'; const paramParts = rawStr.split(/&(?=[a-zA-Z_]+=)/); // 结果为 [rawStr] // 若需将单个值作为指定参数的值 const params = new URLSearchParams(); params.append('biome', paramParts[0]); console.log(params.get('biome')); // Temparate Grasslands, Savannas & Shrublands
说明
长期解决方案是修改UI,避免用户直接输入查询字符串(比如用单独输入框收集每个参数),上述方法可临时解决当前解析问题。
内容的提问来源于stack exchange,提问作者punkish
相关产品推荐
相关产品推荐

