Edge 瀏覽器 URLSearchParams bug 修復

背景

URLSearchParmas API 爲 URL 的查詢字符串(query string)提供了方便操作的接口,管理端的項目大多都應用了該接口,但這個 API 因爲部分瀏覽器沒有實現(如 IE 和舊版 Edge,詳見),所以引入了相應的 polyfill(github.com/WebReflection/url-search-params )進行支持,npm 包名爲 url-search-params

URLSearchParams 的使用方式使用詳見這裏

存在問題

隨着2018年4月 windows 10 系統的更新發布,Edge 瀏覽器的排版引擎升級到了17,開始支持 URLSearchParams API。但是由於存在一些 bug,而且引入的 polyfill 也沒有發現並進行處理,所以導致管理端的項目在 Edge 瀏覽器上請求時,在一定條件下會出現參數錯誤,最後導致請求失敗。

如何復現

當請求參數中,但參數值同時出現“&”符號和“ ”空格時,URLSearchParamstoString() 方法就會出問題。

舉個例子,下面是一個參數 q ,值爲 a & b ,預期“ ”轉爲“+”,“&”轉爲"%26" :

const params = new URLSearchParams({q: 'a & b'});
params.toString();
// 期望返回“q=a+%26+b”,Edge 17瀏覽器則返回了“q=a+&+b”

從上面結果可以看出,Edge 17沒有成功轉義“&”符,由於這個字符是用於分割參數的,這樣原本只有一個參數 q='a & b' ,但是由於沒有成功轉義”&“,就變成 q='a '' b'='' (注意 b 前面有一個空格)兩個參數了,改變了原本的請求參數。

如何解決

解決方法

Plan A

原有 polyfill 的 GitHub 代碼內沒有對一些實現不規範的 URLSearchParams API 進行替換處理,解決改問題需要在模塊引入前先清掉瀏覽器的 API( window.URLSearchParams 設爲 undefined ),模塊引入時就會賦予一個代碼實現的 API。

原本打算在沿用舊有的 polyfill 上,不改變舊的 npm 包,應用上述方法進行修復。但是要在引用 polyfill 之前插入一段代碼判斷,會增加了代碼耦合,所以放棄了。還有一種是直接在原有的 polyfill 代碼上改,但由於該項目用 make 命令進行構建,對此不太熟悉,並且作者已將該項目轉移到新的項目進行維護,構建方式也改了,最後就放棄了。

Plan B

原有 polyfill 由於已經轉移到新的 Github 項目進行維護(github.com/ungap/url-search-params),構建也改爲 npm 進行構建,npm 包名改爲 @ungap/url-search-params,前面加了個 scope

在新的 polyfill 項目代碼中,作者這次有對不規範的 URLSearchParams API 進行判斷和替換,這樣恰好也能在此添加 Edge 瀏覽器的判斷。

於是就可以 fork 該項目代碼修改和測試,然後給該項目提了個 pull request 給作者,很快作者就合併了代碼,併發布了新的 npm 包。

然後,先把原來的 npm 包卸載,然後替換上新的 npm 包。

# 卸載
npm uninstall --save url-search-params
# 安裝
npm install --save @ungap/url-search-params

最後,把模塊引入的代碼改下。

import URLSearchParams from 'url-search-params';
// 改爲
import URLSearchParams from '@ungap/url-search-params';

最後

最近,微軟官方宣佈 Edge 瀏覽器將放棄 EdgeHTML 內核,將採用 Chromium 內核,前端開發紛紛期待新 Edge 到來。不過時間應該還長,而且用戶升級也要時間,所以大家還是趕緊修復。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章