likes
comments
collection
share

快看,你的xxxdecode()乱码啦🤬

作者站长头像
站长
· 阅读数 21

一次跟对接方协商通过连接携带QueryString的方式传输一些关键信息,但就是这个不起眼的地方,因为对编码模糊的认识,可好一顿折腾, 大概操作是对方提供的方法,会依次对参数做JSON.stringfy()、encodeURIComponent(),但是我说我们参数可能会带有中文等内容,然后就在中间加了一道base64.encode(),好的,问题就这样开始产生了🥵

先说结果👇

排查过程很简单,首先排除我自己数据的问题(主打的就是一个自信),然后就是服务方提供的API,还有经过服务器之后拿到的参数,一对比发现了猫腻,编码过的字符串里面所有的"%2B"经过服务器回来全变成了"%20",对应的字符分别就是"+"" ",好了这下就好办了,"+"不用说,经过Base64.encode( )他就会有,那他为啥会变成空格?

  • 首先是Content-type: application/x-www-form-urlencoded,在MDN里面关于encodeURLComponent()的描述里面我发现这样一句话, 快看,你的xxxdecode()乱码啦🤬 点开链接跳转到whatwg里面相关描述, 快看,你的xxxdecode()乱码啦🤬

快看,你的xxxdecode()乱码啦🤬 也就是说如果请求是这种方式,那很有可能会被错误转换掉。

  • 其次是服务端,它在解析QueryString的时候,URLDdcoder也会这样处理也是采用上面方式编、解码 快看,你的xxxdecode()乱码啦🤬 "."、"-"、"*"、"_"他们会保留,"+"" "互相convert,所有的问题就出这里。要解决就很简单,一个是从源头使用Base64URL这种针对URL编码做了修改的编码方式,不产生"+"就永远不会有这个问题;其次就是统一对空格的编、解码方式,自然也就没有问题了。

边界拓展👋

每次查资料都是自己对自己知识边界的疯狂摩擦

  • lone surrogate 先贴张图片,这个是MDN关于encodeURIComponent()的异常描述,当时就没看懂,反手一个翻译“孤独的 代理人”,更是傻眼。 快看,你的xxxdecode()乱码啦🤬 顺着链接跳转到String的描述,往下面翻有一个段落对UTF-16还有这个名词都做了简要解释的,

快看,你的xxxdecode()乱码啦🤬 这下就能知道个大概,它这是出于UTF-16编码规则来的, 其实简单就可以这样理解,在UTF-16里面,对于超出两个字节编码的字符集,通过一个叫代理对(surrogagate pairs)的东西,包含一个高位代理、一个低位代理共四字节来表示一个字符,这个高低代理位分别用一个划分一个固定的不代表任何字符集的区间,就是上图中描述的区间来标识。JS里面encode方法不同于其他方法,是使用UTF-8编码,对于这些方法,可以通过isWellFormed()方法来判断字符串是否是一个well-formed string


相关资料🗂️

🏷️MDN 🏷️whatwg 🏷️Unicode编码及UTF-32, UTF-16 和 UTF-8