相信大家都有組 query string 的需求,乍看之下寫起來不難
function toQueryString(obj) {
return Object.entries(obj).map(([key, value]) => {
return `${key}=${value}`;
}).join('&');
}
toQueryString({ a:1, b:2 })
// => "a=1&b=2"
這樣寫如果 key 或 value 有 &
或 =
就行不通了,還可能有被注入參數的安全疑慮 😨
toQueryString({ a:1, b: '2&c=3' })
// => "a=1&b=2&c=3"
那要怎麼改呢?答案是用 encodeURIComponent
function toQueryString(obj) {
return Object.entries(obj).map(([key, value]) => {
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
}).join('&');
}
toQueryString({ a:1, b: '1&c=3'})
// => "a=1&b=1%26c%3D3"
那麼要怎麼解析 query string 呢?試著寫一下
function fromQueryString(qs) {
return qs.split('&').reduce((result, pair) => {
const [key, value] = pair.split('=');
result[decodeURIComponent(key)] = decodeURIComponent(value);
return result;
}, {});
}
fromQueryString("a=1&b=1%26c%3D3")
// => {a: "1", b: "1&c=3"}
看起來不錯,但是有一個問題是無法解析重複的 key(還真的有這種存在)
fromQueryString("a=1&a=2")
// => {a: "2"}
我們可以再改一下我們的 code 加個處理之類的,這時候已經有點累了,有沒有更快的方法?
答案是用 browser 內建的 URLSearchParams 來做,上述的 case 都可以處理得到。文件寫得很清楚,就不介紹了。
別再自己操作 query string 了啦!