最近在实现一个小工具的一个小功能,发现 URL 中的逗号会让 URL 在一些软件并不会被识别为一段连续的链接
http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1
这时候需要做的就是对 URL 进行 Encoding 了,能够将逗号进行转义。
JS URL 编码
encodeURI
encodeURI() 函数可把字符串作为 URI 进行编码。
- 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:
- _ . ! ~ * ' ( )
- 该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:
;/?:@&=+$,#
以 'http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1'
为例:
url = 'http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1'
encodeURI(url)
"http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1"
可以看到并没有对逗号字符进行编码,链接中仍在存在,不符合我们的目标。
decodeURL
decodeURI() 函数可对 encodeURI() 函数编码过的 URI 进行解码。
decodeURI(encodeURI(url))
"http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1"
encodeURIComponent
encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。
- 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码:
- _ . ! ~ * ' ( )
- 其他字符(比如 :
;/?:@&=+$,#
这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的
encodeURIComponent(url)
"http%3A%2F%2Fxxx.example.com%2F%23%2Fhahaha%3Fa%3D1589760000000%26b%3D1589760000000%26c%3D2%2C3%2C1"
可以看到通过 encodeURIComponent
方法对 URl 编码以后的链接可读性已经非常差了,同时如果复制链接生成的 URL 在浏览器中是打不开目标页面的,不符合我们的目标。
decodeURIComponent
decodeURIComponent() 函数可对 encodeURIComponent() 函数编码的 URI 进行解码。
let a = encodeURIComponent('http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1')
decodeURIComponent(a)
"http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2,3,1"
解决方案
考虑到纯将 url 中的逗号通过正则直接全部替换不够优雅,或者说不够抽象,这里也就放弃了,直接转公共的方法
将 params 部分进行转义,保留 ?
之前的字符串
- 将 URL 从
?
截取为两段(pathnameURL & paramsURL) - 将 paramsURL 进行转义
- 拼接
大致代码如下:
// encodeURIComponent params
function encodeGetParams(p) {
return Object.entries(p)
.map(kv => kv.map(encodeURIComponent).join('='))
.join('&')
}
// get url query
function getUrlParams(url) {
if (typeof url !== 'string') {
console.warn('para url is not a string')
return
}
const vars = {}
url.replace(/[?&]+([^=&]+)=([^&]*)/gi, (m, key, value) => {
vars[key] = value
})
return vars
}
const url = window.location.href
const enUrl = `${url.split('?')[0]}?${this.encodeGetParams(this.getUrlParams(url))}`
// enUrl = http://xxx.example.com/#/hahaha?a=1589760000000&b=1589760000000&c=2%2C3%2C1"
最后得到的 enUrl
即为需要的结果。
vue 指令版
占坑
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于