JavaScript URL 编码 & 解码

本贴最后更新于 1409 天前,其中的信息可能已经时异事殊

最近在实现一个小工具的一个小功能,发现 URL 中的逗号会让 URL 在一些软件并不会被识别为一段连续的链接dogedoge

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 指令版

占坑doge dogedogedogedoge

  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    710 引用 • 1173 回帖 • 192 关注
  • URL
    11 引用 • 30 回帖
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1347 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...