encodeURIComponent 与 URLSearchParams 的不同输出
Different output from encodeURIComponent vs URLSearchParams
我使用 URLSearchParmas
API 构建了一个带有查询参数的 oauth2 url。但是,输出 URL 没有 return 预期的 url。谁能帮助我理解这两个 API 之间的区别,以及如何使用 URLSearchParams
获得与 encodeURIComponent
的输出相同的结果?谢谢!
const expected = encodeURIComponent('code id_token'); // code%20id_token
const search = new URLSearchParams();
search.set('response_type', 'code id_token');
search.toString(); // code+id_token
根据 WHATWG,URLSearchParams
使用 application/x-www-form-urlencoded
格式。虽然它适用于解码 URL 查询,但对于编码它可能会导致意想不到的结果,例如空格被编码为 +
和额外字符(例如 ~
被百分比编码)。最好使用 encodeURIComponent
代替:
有对象:
const params = {
text1: 'aaa bbb',
text2: '-._*~()'
}
而不是:
url.search = (new URLSearchParams(params)).toString()
使用:
url.search = Object.entries(params)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&')
另外,根据MDN even encodeURIComponent
doesn't conform to newer RFC 3986 which defines more characters to escape, for example *
. While it's probably safe not to escape these additional characters if you aren't using them as field separators, if you want to be strictly conformant to latest RFC, use this updated implementation from MDN:
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase();
});
}
试验场:
const params = {
text1: 'aaa bbb',
text2: '-._*~()'
}
const url1 = new URL('http://example.com')
const search1 = new URLSearchParams(params)
url1.search = search1 // Incorrect
console.log('URLSearchParams', url1.toString())
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
const url2 = new URL('http://example.com')
const search2 = Object
.entries(params)
.map(([key, value]) => `${fixedEncodeURIComponent(key)}=${fixedEncodeURIComponent(value)}`)
.join('&')
url2.search = search2 // Correct
console.log('fixedEncodeURIComponent', url2.toString())
我使用 URLSearchParmas
API 构建了一个带有查询参数的 oauth2 url。但是,输出 URL 没有 return 预期的 url。谁能帮助我理解这两个 API 之间的区别,以及如何使用 URLSearchParams
获得与 encodeURIComponent
的输出相同的结果?谢谢!
const expected = encodeURIComponent('code id_token'); // code%20id_token
const search = new URLSearchParams();
search.set('response_type', 'code id_token');
search.toString(); // code+id_token
根据 WHATWG,URLSearchParams
使用 application/x-www-form-urlencoded
格式。虽然它适用于解码 URL 查询,但对于编码它可能会导致意想不到的结果,例如空格被编码为 +
和额外字符(例如 ~
被百分比编码)。最好使用 encodeURIComponent
代替:
有对象:
const params = {
text1: 'aaa bbb',
text2: '-._*~()'
}
而不是:
url.search = (new URLSearchParams(params)).toString()
使用:
url.search = Object.entries(params)
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
.join('&')
另外,根据MDN even encodeURIComponent
doesn't conform to newer RFC 3986 which defines more characters to escape, for example *
. While it's probably safe not to escape these additional characters if you aren't using them as field separators, if you want to be strictly conformant to latest RFC, use this updated implementation from MDN:
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase();
});
}
试验场:
const params = {
text1: 'aaa bbb',
text2: '-._*~()'
}
const url1 = new URL('http://example.com')
const search1 = new URLSearchParams(params)
url1.search = search1 // Incorrect
console.log('URLSearchParams', url1.toString())
function fixedEncodeURIComponent(str) {
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
return '%' + c.charCodeAt(0).toString(16).toUpperCase()
})
}
const url2 = new URL('http://example.com')
const search2 = Object
.entries(params)
.map(([key, value]) => `${fixedEncodeURIComponent(key)}=${fixedEncodeURIComponent(value)}`)
.join('&')
url2.search = search2 // Correct
console.log('fixedEncodeURIComponent', url2.toString())