Uncaught URIError: URI malformed 报错如何解决?

Situation

前几天遇到一个线上问题反馈,用户的某一个文件访问对应的页面时,加载不出来,其他文件都没有问题,拿到这个文件后一看,大概知道了原因,文件名称包含了 % ,name作为query参数拼接到了url后面,name没有做编码,导致浏览器自动解码时遇到 % 报错,结果给用户的表现就是页面空白,啥也没有。

js 复制代码
decodeURIComponent('%');

运行后,浏览器抛出错误:

js 复制代码
Uncaught URIError: URI malformed

这是因为 % 在 URL 编码中有特殊意义,而 decodeURIComponent 解析时会严格按照 百分号编码规则 来处理。

URIError 是 js 的内置错误类型,表示 URI 相关的错误。在解析 URI 编码时,如果遇到非法格式,就会抛出这个错误

Action

如何解决这个问题呢?

1、凡是query中字符串可能存在 % 等特殊字符的情况下,都需要encode编码后再传参

js 复制代码
name: encodeURIComponent(name)

同时,在接收方解析url的query参数时,需要使用try catch包裹,避免代码报错阻塞后续流程进行。但这只是容错方式,并不是根本解决办法,比如上述线上问题还是需要编码query参数才能解决,因为报错在浏览器自动decode解码环节,代码还没执行到接收方呢


js 复制代码
function safeDecodeURIComponent(str) {
    try {
        return decodeURIComponent(str);
    } catch (e) {
        console.warn('非法 URI 编码:', str);
        return str;
    }
}

2、使用标准 API 解析参数

URLSearchParams 是浏览器提供的一个内置 Web API,专门用来操作 URL 的query参数,可以帮我们解析、获取、设置、删除、遍历 URL 的参数,而不需要自己手写 split('?')、split('&') 这种容易出错的代码

js 复制代码
const params = new URLSearchParams(location.search);
console.log(params.get('name'));

decodeURI和decodeURIComponent

特性 decodeURI decodeURIComponent
解码范围 解码整个 URI,但不会解码保留字符(?、&、#、= 等) 解码 URI 组件,所有非字母数字和保留字符都会被解码
作用目标 用于解析完整 URL 字符串 用于解析 URL 的片段(如 query 参数值)
是否保留结构 会保留 URL 的结构,不会破坏参数分隔符 可能会解码结构字符,从而破坏 URL 格式
输入 example.com/search?q=%E... %E4%BD%A0%E5%A5%BD
输出 example.com/search?q=你好 你好

开发过程中需求是解析query参数&保留特殊字符,所以基本都是使用的decodeURIComponent

Result

遇到 Uncaught URIError: URI malformed,不要只是 try-catch 一下了事,而是应该:

  1. 确认数据源是否正确编码
  2. 区分 decodeURI 与 decodeURIComponent
  3. 对外部数据加防御性解析

只要保证 URL 里 path字段没有裸%,就不会有 URIError。

参考

URIError:developer.mozilla.org/zh-CN/docs/...

URLSearchParams:developer.mozilla.org/zh-CN/docs/...

相关推荐
共享家95275 小时前
搭建 AI 聊天机器人:”我的人生我做主“
前端·javascript·css·python·pycharm·html·状态模式
Halo_tjn6 小时前
基于封装的专项 知识点
java·前端·python·算法
摘星编程7 小时前
OpenHarmony环境下React Native:自定义useTruncate文本截断
javascript·react native·react.js
Duang007_7 小时前
【LeetCodeHot100 超详细Agent启发版本】字母异位词分组 (Group Anagrams)
开发语言·javascript·人工智能·python
2601_949868369 小时前
Flutter for OpenHarmony 电子合同签署App实战 - 主入口实现
开发语言·javascript·flutter
m0_748229999 小时前
Vue2 vs Vue3:核心差异全解析
前端·javascript·vue.js
C澒9 小时前
前端监控系统的最佳实践
前端·安全·运维开发
xiaoxue..9 小时前
React 手写实现的 KeepAlive 组件
前端·javascript·react.js·面试
摘星编程9 小时前
在OpenHarmony上用React Native:自定义useHighlight关键词高亮
javascript·react native·react.js
hhy_smile9 小时前
Class in Python
java·前端·python