背景
最近有个新项目使用vuecli4 vue3 来开发,其中一个需求是从url解析出参数,然后发送后端解密查询。开发时一直使用明文,所以未出现这种情况。在转测后使用加密 &content={"orderNo":"aaaaa+bbbb"};结果route.query 解析成 content={"orderNo":"aaaaa bbbb"}。惊不惊喜,意不意外?难道祖师爷写了bug?
思考方向
- 编码问题
- 祖师爷写bug 我赶快兴冲冲的去 fork vue-router.我要在简历上写上 vue-router: contributor.
源码分析
- 全局找到 query。定位到 src/util/query.js。
const encode = str =>
encodeURIComponent(str)
.replace(encodeReserveRE, encodeReserveReplacer)
.replace(commaRE, ',')
export function decode (str: string) {
try {
return decodeURIComponent(str)
} catch (err) {
if (process.env.NODE_ENV !== 'production') {
warn(false, `Error decoding "${str}". Leaving it intact.`)
}
}
return str
}
控制台测试编码问题: encodeURIComponent、decodeURIComponent 对于 + 号也是正确编码解码的。那只能排除编码问题。现在就剩下 祖师爷写bug 了。
function parseQuery (query: string): Dictionary<string> {
const res = {}
query = query.trim().replace(/^(\?|#|&)/, '')
if (!query) {
return res
}
query.split('&').forEach(param => {
const parts = param.replace(/\+/g, ' ').split('=')
const key = decode(parts.shift())
const val = parts.length > 0 ? decode(parts.join('=')) : null
if (res[key] === undefined) {
res[key] = val
} else if (Array.isArray(res[key])) {
res[key].push(val)
} else {
res[key] = [res[key], val]
}
})
return res
}
我们发现了问题所在:param.replace(/+/g, ' ').split('=')。大家都明白了,问题出在这里。祖师爷为什么要特殊处理 + 号? 到这里还是想不明白为什么要这样做, 难道是 param的问题?那我们就接着找param 到底是什么。经过一步一步往上找,我们在 src/util/path.js
export function parsePath (path: string): {
path: string;
query: string;
hash: string;
} {
let hash = ''
let query = ''
const hashIndex = path.indexOf('#')
if (hashIndex >= 0) {
hash = path.slice(hashIndex)
path = path.slice(0, hashIndex)
}
const queryIndex = path.indexOf('?')
if (queryIndex >= 0) {
query = path.slice(queryIndex + 1)
path = path.slice(0, queryIndex)
}
return {
path,
query,
hash
}
}
这个 query 就是 src/util/lacation.js normalizeLocation() parsePath() 传过来的 location.search 里面的参数(aaa=bb&cc=dd)。那么到这里,我更相信肯定有我不知道的未知原因,而不是说 祖师爷写bug了。于是我又百度了。找到了阮一峰老师的关于URL编码。好吗 一通看下来,url编码虽然混乱,但是和 param.replace(/+/g, ' ') 这个操作有什么关系呢。没办法,只能百度一个一个往下点。直到我看到这句话
url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值,如何是好?
可能在服务器无法获得正确的参数值。。。服务端,我问了我们的java:都是正常可以获取的啊!只要你传的对,我肯定能获取啊。 nice 对就是这样。没毛病!
求助
哪位大佬能告诉我下服务端到底用的什么解码格式 获取不了正确的参数?