首頁 > web前端 > js教程 > JavaScript 中 URL 和 URLSearchParams 的陷阱

JavaScript 中 URL 和 URLSearchParams 的陷阱

Mary-Kate Olsen
發布: 2024-11-28 11:59:09
原創
492 人瀏覽過

Pitfalls of URL and URLSearchParams in JavaScript

一切都始於一個錯誤

在 JavaScript 和 Node.js 中使用 URL 應該很簡單,但是我們專案中最近的一個錯誤讓我陷入了 URL 和 URLSearchParams API 中微妙怪癖的兔子洞。這篇文章將探討這些怪癖,它們如何在您的程式碼中引起問題,以及您可以採取哪些措施來避免它們。


問題:使用 Axios 處理 URL

我們在生成 URL 並向其添加哈希簽名時遇到了此問題。查詢參數的百分比編碼不一致,導致意外行為和錯誤的雜湊簽章。

很明顯,URL 和 URLSearchParams 物件之間的互動需要格外小心。


陷阱#1:URL.search 與 URLSearchParams.toString()

第一個驚喜是 URL.search 和 URLSearchParams.toString() 之間的差異。

使用 .searchParams 修改 URL 時要小心,因為根據 WHATWG 規範,URLSearchParams 物件使用不同的規則來決定要對哪些字元進行百分比編碼。例如,URL 物件不會對 ASCII 波形符 (~) 字元進行百分號編碼,而 URLSearchParams 將始終對其進行編碼。

// Example 1
const url = new URL("https://example.com?param=foo bar");
console.log(url.search); // prints param=foo%20bar
console.log(url.searchParams.toString()); // prints ?param=foo+bar

// Example 2
const myURL = new URL('https://example.org/abc?foo=~bar');
console.log(myURL.search);  // prints ?foo=~bar
// Modify the URL via searchParams...
myURL.searchParams.sort();
console.log(myURL.search);  // prints ?foo=%7Ebar
登入後複製
登入後複製

在我們的專案中,我們需要明確地重新指派 url.search = url.searchParams.toString() 以確保查詢字串的編碼一致。


陷阱#2:加號困境

另一個問題是 URLSearchParams 如何處理字元。預設情況下,URLSearchParams 解釋為空格,這在編碼二進位資料或 Base64 字串時可能會導致資料損壞。

const params = new URLSearchParams("bin=E+AXQB+A");
console.log(params.get("bin")); // "E AXQB A"
登入後複製
登入後複製

一種解決方案是在將值附加到 URLSearchParams 之前使用encodeURIComponent:

params.append("bin", encodeURIComponent("E+AXQB+A"));
登入後複製

更多詳細資訊請參閱 MDN 文件。


陷阱 #3:URLSearchParams.get 與 URLSearchParams.toString()

比較 URLSearchParams.get 和 URLSearchParams.toString 的輸出時會出現另一個微妙之處。例如:

const params = new URLSearchParams("?key=value&key=other");
console.log(params.get("key")); // "value" (first occurrence)
console.log(params.toString()); // "key=value&key=other" (all occurrences serialized)
登入後複製

在多值場景中,get 只傳回第一個值,而 toString 則是序列化所有值。


我們程式碼庫中的修復

在我們的專案中,我們透過明確重新分配搜尋屬性解決了這個問題:

url.search = url.searchParams.toString();
url.searchParams.set(
  "hash",
  cryptography.createSha256HmacBase64UrlSafe(url.href, SECRET_KEY ?? "")
);
登入後複製

這確保了在新增雜湊值之前所有查詢參數都已正確編碼。


Node.js 查詢字串模組

WHATWG URLSearchParams 介面和 querystring 模組具有類似的用途,但 querystring 模組的用途更通用,因為它允許自訂分隔符號(& 和 =)。另一方面,URLSearchParams API 純粹是為 URL 查詢字串而設計的。

querystring 比 URLSearchParams 效能更高,但不是標準化 API。當效能不重要或需要與瀏覽器程式碼相容時,請使用 URLSearchParams。

與 querystring 模組不同,使用 URLSearchParams 時,不允許數組值形式的重複鍵。陣列使用 array.toString() 進行字串化,它只是用逗號連接所有陣列元素。

// Example 1
const url = new URL("https://example.com?param=foo bar");
console.log(url.search); // prints param=foo%20bar
console.log(url.searchParams.toString()); // prints ?param=foo+bar

// Example 2
const myURL = new URL('https://example.org/abc?foo=~bar');
console.log(myURL.search);  // prints ?foo=~bar
// Modify the URL via searchParams...
myURL.searchParams.sort();
console.log(myURL.search);  // prints ?foo=%7Ebar
登入後複製
登入後複製

使用querystring模組,查詢字串'foo=bar&abc=xyz&abc=123'被解析為:

const params = new URLSearchParams("bin=E+AXQB+A");
console.log(params.get("bin")); // "E AXQB A"
登入後複製
登入後複製

重點

  1. 小心 URLSearchParams 處理特殊字元(例如 ~)和空格。必要時使用encodeURIComponent。

  2. 了解 URL.search、URLSearchParams.get 和 URLSearchParams.toString 之間的區別,以避免意外行為。

  3. 在 Node.js 中,如果要將重複的查詢參數鍵解析為數組,請使用查詢字串模組。

以上是JavaScript 中 URL 和 URLSearchParams 的陷阱的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板