history.push传参时URL中^符号编码异常报URI malformed问题
URL脱字符
^编码抛出URIError: URI malformed修复方案 问题表现
- 传递包含脱字符
^、百分号%的URL参数时,参数解析阶段控制台抛出URIError: URI malformed错误 - 手动调用
encodeURIComponent编码参数后传入history.push,最终生成的URL和编码预期不符:^的编码结果%5E被自动还原为原始字符^,%的编码结果%25被自动还原为原始字符%,形成无效URL编码序列 - 测试参数值:
- companyName:
Test Character )(*&(^&%^%$#@)( - branchName(分支名):
Test Character Branch !@#$@%^&
- companyName:
- 异常URL与预期URL对比:
// 控制台打印的异常URL http://localhost:3005/branch-management/edit-branch/?companyName=Test%20Character%20)(*%26(^%26%^%24%23%40)(&branchName=Test%20Character%20Branch%20!%40%23%24%40%^%26 // 浏览器地址栏显示的异常URL http://localhost:3005/branch-management/edit-branch/?companyName=Test%20Character%20)(*%26(^%26%^%%24%23%40)(&branchName=Test%20Character%20Branch%20!%40%23%24%40%^%26 // 预期正确URL http://localhost:3005/branch-management/edit-branch/?companyName=Test%20Character%20)(*%26(%5E%26%25%5E%25%24%23%40)(&branchName=Test%20Character%20Branch%20!%40%23%24%40%25%5E%26
核心原因
history.push传参写法错误:将查询字符串直接拼接在pathname字段中传递,路由库处理pathname时,会默认执行一次解码+重新编码的流程,该逻辑会将^判定为URL路径允许的非转义字符,自动把已编码的%5E还原为^,同时连带将相邻的%25(%的编码)还原为原始%,形成孤立的、不符合编码规范的百分号,最终触发解码错误。- 自定义参数解析逻辑存在缺陷:手写正则匹配参数时,遇到未编码的特殊字符会提前截断参数值,后续调用
decodeURIComponent时,残缺的参数中存在无效转义序列,直接抛出URI格式错误。
修复方案
1. 修正路由跳转传参逻辑
不要将查询参数拼接在pathname中,使用路由对象的search字段单独传递查询参数,推荐直接用标准URLSearchParamsAPI处理参数编码,避免路由库二次处理破坏编码结果:
const selectRow = async (code, companyName, e) => { e.preventDefault(); // 构造查询参数对象,自动完成符合规范的编码 const searchParams = new URLSearchParams({ companyName: companyName, branchName: code }); history.push({ pathname: '/branch-management/edit-branch/', search: searchParams.toString() }); };
不推荐手动拼接pathname后对特殊字符做二次编码的写法,后续迭代容易遗漏转义规则产生新问题。
2. 替换手写参数解析逻辑
放弃正则手写解析的方案,直接使用标准URLAPI解析查询参数,从根源避免正则截断、解码报错问题:
export const getParameterByName = (name, url = window.location.href) => { const urlInstance = new URL(url); return urlInstance.searchParams.get(name); };
如果存在兼容旧浏览器的需求必须保留手写逻辑,需要在解码前先清洗无效转义序列,避免decodeURIComponent报错:
export const getParameterByName = (name, url = window.location.href) => { name = name.replace(/[\\[\]]/g, "\\$&"); const regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), results = regex.exec(url); if (!results) return null; if (!results[2]) return ""; // 预处理非法编码序列,兼容被异常解码的特殊字符 const safeValue = results[2] .replace(/\+/g, " ") .replace(/%(?![0-9A-Fa-f]{2})/g, "%25") .replace(/\^/g, "%5E"); return decodeURIComponent(safeValue); };
验证结果
修复后路由跳转将自动生成符合编码规范的URL,^、%等特殊字符会被正确转义,参数解析阶段不会再抛出URIError: URI malformed错误,可以正常获取原始参数值。
内容的提问来源于stack exchange,提问作者Fatt Sky
相关产品推荐
相关产品推荐

