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 到来。不过时间应该还长,而且用户升级也要时间,所以大家还是赶紧修复。

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