现在有一个待解析的字符串,例如
const str = 'a=1+2&b=1'
希望用node自带的querystring.parse函数解析,预计获得这样的结果
{
a: '1+2',
b: '1'
}
然而实际的结果却是
querystring.parse(str)
// { a: '1 2', b: '1' }
问题点:为什么+号被解析成了空格?
querystring.parse源码分析
源码地址: github.com/nodejs/node…
思路大致分析(以一个简单字符串解析为例):
querystring.parse('a=1+1&b=2')
-
获取默认分隔符和等号(unicode编码)
const sepCodes = [38] // '&'
const eqCodes = [61]; // '='
-
遍历传入的字符串('a=1+1&b=2')
-
判断当前是否为分割符 - 字符unicode === 38,或判断当前是否为赋值符号 - unicode === 61
-
若是,对其进行分割操作,为后续取key,v做一些工作
-
判断当前字符是否为 ‘+’
-
若是,则替换成‘ ’ (以此时传入querystring.parse的参数来说)
当前方案如何解决该问题
若不改变目前已拥有的字符串,通过何种方式能获取我们所需的对象呢
解决方案: 事先先将 + 号手动替换成%2B , 或者自己写一个解析函数
querystring.parse('a=1+1&b=2'.replace(/\+/g, '%2B')) // 事先将+号替换成%2B,内部对获取的value还会做一次decode
为什么querystring.parse要将+号处理成’ ‘呢?为什么不是‘ - ’号
关于空格的编码,目前存在两种
-
html4定义: 空格应该被编码成加号"+",而如果字符本身就是加号"+",则应该被编码成%2B
-
RFC-3986定义: 采用统一的编码方式,字符的编码格式为:%HH(H为十六进制字符), 并没有对空格做特殊处理。按照RFC-3986规范,空格被编码成%20,而加号"+"被编码成%2B。
因此,可以理解为何parse时会对+号做特殊处理