包含换行的字符串被Base64编码后,解码报错 URI malformed 的问题排查
背景:
我的网站有一个类似 TODO 的服务,功能就是前端传入一个字符串,后端进行 base64 编码,前端展示的时候解码。平时主要都是存一些英文链接什么的,今天偶然传入一段中文后,页面报错。
排查:
报错是 URI malformed
,说明应该是使用 URI 相关函数出了问题,看了后端返回的内容,拿去在别的网站进行解码,正常,而且在这个网站编码后,与后端的结果一致。因此跑去翻看网站代码:
1 | export function base64ToPlain(base64: string) { |
这是解码的函数,定位到应该是解码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 来取后两位即可,代码如下:
1 | export function base64ToPlain(base64: string) { |
补充:LF 换行是%0A,CRLF 换行是%0D%0A
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 limkim的个人博客!