添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

我的网站有一个服务,功能就是前端传入一个字符串,后端进行base64编码,前端展示的时候解码。平时主要都是存一些英文链接什么的,今天偶然传入一段中文后,页面报错。

报错是 URI malformed ,说明应该是使用URI相关函数出了问题,看了后端返回的内容,拿去在别的网站进行解码,正常,而且在这个网站编码后,与后端的结果一致。因此跑去翻看网站代码:

export function base64ToPlain(base64: string) {
    const utf8 = [...window.atob(base64)].map(item => '%' + item.charCodeAt(0).toString(16)).join('');
    return decodeURIComponent(utf8);

这是解码的函数,定位到应该是解码decodeURIComponent出现了问题,断点调试发现,utf8是下面这样的字符串:
"%e4%b8%80%e4%b8%aa%e9%a1%b9%e7%9b%ae%ef%bc%9b%a%e8%87%b3%e5%b0%91"

十分眼熟哦,这不就是小写后的URI编码的样子吗,难道是因为大小写,于是果断加上toUpperCase(),但是没起作用,想想也是,之前都是小写,肯定大小写不敏感。那问题应该是出在这串字符上,格式会不会有错误呢。仔细过了一遍,还真有!中间有一个%a。经过排查,这个字符在换行回车的时候会出现,单独对回车编码,发现是%0A。所以报错原因就是少了个0

既然问题找到,那么就看如何解决,不难看出代码中item.charCodeAt(0).toString(16),在转16进制时,会将10转为a而不是0a,因此,我们想办法在前面补0就可以了,可以做判断后补0,也可以统一补0,再使用slice来取后两位即可,代码如下:

export function base64ToPlain(base64: string) {
    const utf8 = [...window.atob(base64)].map(item => '%' + ('0' + item.charCodeAt(0).toString(16)).slice(-2)).join('');
    return decodeURIComponent(utf8);

补充:LF换行是%0A,CRLF换行是%0D%0A

OpenClash代理时,谷歌应用商店无法下载应用问题的排查解决记录 使用node Express转发文件流请求 记一次包含换行字符串Base64编码后,解码报错 URI malformed MongoDB 之 Mongoose 学习 -- Connection canvas高度100%或与视口高度一致,仍出现滚动条 OpenClash代理时,谷歌应用商店无法下载应用问题的排查解决记录 vue3 checkbox使用v-model:value绑定reactive声明的值时响应式失效 PUT和POST的区别 JS中console的几种方法 程序代码中,怎么区分status和state?