常用ASCII URL编码对照表,JavaScript中如何把url的%20、%22、%28、%29、%7B、%7D解析还原成真实的字符
由于url支持26个英文字母、数字和少数几个特殊字符,因此,对于url中包含非标准url的字符时,就需要对其进行编码。
【问题描述】:
笔者遇到过这样一个需求,在http的拦截器中拦截url并添加一些额外的参数,代码如下:
// http request 拦截器
// instance: axios实例
this.instance.interceptors.request.use(
config => {
const authParams: any = LocalStorage.get(STORAGE_KEY.IFRAME_PARAMS)
// 替换url,替换参数
const {url, baseURL, params} = config
let [pathname, search] = url.split('?')
const temp = search ? this.parseParams(search) : {}
Object.assign(temp, authParams) // 覆盖原请求中的部分参数
const newParams = this.getQueryString(temp)
config.url = newParams ? `${pathname}?${newParams}` : pathname // 使用?拼接成新的url
return config
},
err => {
return Promise.reject(err)
})
/**
* @desc 解析跳转进来的路由参数,为对象
* '?type=1&iframe=true'
* =>
* {type: "1"
iframe: "true"
}
*/
parseParams(search) {
const ret = {},
seg = search.replace(/^\?/, '').split('&'),
len = seg.length
let i = 0, s
for (; i < len; i++) {
if (!seg[i]) {
continue
}
s = seg[i].split('=')
ret[s[0]] = s[1]
}
return ret
}
比如拦截http请求(1):https://xxx.com/report/list?title=customer_number&endTime=2020-06-30%2023:59:59&startTime=2020-06-01%2000:00:00&pageSize=20¤tPageNo=1
添加参数后变成请求(2):https://xxx.com/report/list?timestamp=1595314770&sign=9bc3fd371169e2b4fb6184ed081b0817¤tPageNo=1&pageSize=20&startTime=2020-06-01%252000:00:00&endTime=2020-06-30%252023:59:59&title=customer_number
对比可知添加了参数:
// B
{
timestamp: 1595314770,
sign:9bc3fd371169e2b4fb6184ed081b0817
}
我的做法是解析成元url中?后面的参数成object(A),然后把新的参数(B)拼接到A上,再更新新的url的参数,看似逻辑木得问题,但是!发请求的时候就是失败,并且报错:参数[startTime]格式错误,咦,笔者都没有操作startTime啊,怎么会参数错误呢?
【错因查找】:
笔者瞪大着高度近视的小眼睛,观察了半天才发现,原来两个url中的startTime参数真的不一样,
请求(1)中startTime:startTime=2020-06-01%2000:00:00
请求(2)中startTime:startTime=2020-06-01%252000:00:00
额,笔者当时上传的参数未:startTime=2020-06-01 00:00:00,明明是空格(space),肿么变成了%20,又变成了%25呢?原来是特殊字符的锅。。。
由于url支持26个英文字母、数字和少数几个特殊字符,因此,对于url中包含非标准url的字符时,就需要对其进行编码。
较为特殊的字符例如:@&=+$,/?%!*’();:#[]
当客户端发请求时,浏览器会自动对含有这些字符的部分进行处理,根据👇的HTML URL 编码表可以发现,笔者参数中的空格()被转义成了%20,在拦截器中拦截请求时,%又是特殊字符,被转义成了%25,因此请求(2)的startTime会变成2020-06-01%252000:00:00,既然bug找到了,下面就是解决bug啦ღღღღღღ
【解决方法】:
既然请求(1)中2020-06-01 00:00:00被转义成了2020-06-01%2000:00:00,那么我们把2020-06-01%2000:00:00反转义成真实的字符,那么请求(2)中再转义一次也还是正确的,就不会报错啦❀
因此笔者优化了👆的parseParams(),如下,第二行中的decodeURIComponent(search)可以对对编码后的search进行解码,将诸如%20这样的字符解码成特殊字符空格()
parseParams(search) {
const ret = {}, seg = decodeURIComponent(search).replace(/^\?/, '').split('&'), len = seg.length
let i = 0, s
for (; i < len; i++) {
if (!seg[i]) {
continue
}
s = seg[i].split('=')
ret[s[0]] = s[1]
}
return ret
}
【重点知识】:
- JavaScript decodeURIComponent() 函数:用于解码由 encodeURIComponent 方法或者其它类似方法编码的部分统一资源标识符(URI)。
点击F12(或者Fn + F12)打开控制台,输入如下指令:
console.log(decodeURIComponent("%2b"))
把%2b替换为你想查询的16进制(+)即可。
【附录】:
URL 编码 - 从 %00 到 %8f
| ASCII Value | URL-encode | ASCII Value | URL-encode | ASCII Value | URL-encode |
|---|---|---|---|---|---|
| æ | %00 | 0 | %30 | ` | %60 |
| %01 | 1 | %31 | a | %61 | |
| %02 | 2 | %32 | b | %62 | |
| %03 | 3 | %33 | c | %63 | |
| %04 | 4 | %34 | d | %64 | |
| %05 | 5 | %35 | e | %65 | |
| %06 | 6 | %36 | f | %66 | |
| %07 | 7 | %37 | g | %67 | |
| backspace | %08 | 8 | %38 | h | %68 |
| tab | %09 | 9 | %39 | i | %69 |
| linefeed | %0a | : | %3a | j | %6a |
| %0b | ; | %3b | k | %6b | |
| %0c | < | %3c | l | %6c | |
| c return | %0d | = | %3d | m | %6d |
| %0e | > | %3e | n | %6e | |
| %0f | ? | %3f | o | %6f | |
| %10 | @ | %40 | p | %70 | |
| %11 | A | %41 | q | %71 | |
| %12 | B | %42 | r | %72 | |
| %13 | C | %43 | s | %73 | |
| %14 | D | %44 | t | %74 | |
| %15 | E | %45 | u | %75 | |
| %16 | F | %46 | v | %76 | |
| %17 | G | %47 | w | %77 | |
| %18 | H | %48 | x | %78 | |
| %19 | I | %49 | y | %79 | |
| %1a | J | %4a | z | %7a | |
| %1b | K | %4b | { | %7b | |
| %1c | L | %4c | | | %7c | |
| %1d | M | %4d | } | %7d | |
| %1e | N | %4e | ~ | %7e | |
| %1f | O | %4f | %7f | ||
| space(空格) | %20 | P | %50 | € | %80 |
| ! | %21 | Q | %51 | %81 | |
| " | %22 | R | %52 | ‚ | %82 |
| # | %23 | S | %53 | ƒ | %83 |
| $ | %24 | T | %54 | „ | %84 |
| % | %25 | U | %55 | … | %85 |
| & | %26 | V | %56 | † | %86 |
| ' | %27 | W | %57 | ‡ | %87 |
| ( | %28 | X | %58 | ˆ | %88 |
| ) | %29 | Y | %59 | ‰ | %89 |
| * | %2a | Z | %5a | Š | %8a |
| + | %2b | [ | %5b | ‹ | %8b |
| , | %2c | \ | %5c | Œ | %8c |
| - | %2d | ] | %5d | %8d | |
| . | %2e | ^ | %5e | Ž | %8e |
| / | %2f | _ | %5f | %8f |
URL 编码 - 从 %90 到 %ff
| ASCII Value | URL-encode | ASCII Value | URL-encode | ASCII Value | URL-encode |
|---|---|---|---|---|---|
| %90 | À | %c0 | ð | %f0 | |
| ‘ | %91 | Á | %c1 | ñ | %f1 |
| ’ | %92 | Â | %c2 | ò | %f2 |
| “ | %93 | Ã | %c3 | ó | %f3 |
| ” | %94 | Ä | %c4 | ô | %f4 |
| • | %95 | Å | %c5 | õ | %f5 |
| – | %96 | Æ | %c6 | ö | %f6 |
| — | %97 | Ç | %c7 | ÷ | %f7 |
| ˜ | %98 | È | %c8 | ø | %f8 |
| ™ | %99 | É | %c9 | ù | %f9 |
| š | %9a | Ê | %ca | ú | %fa |
| › | %9b | Ë | %cb | û | %fb |
| œ | %9c | Ì | %cc | ü | %fc |
| %9d | Í | %cd | ý | %fd | |
| ž | %9e | Î | %ce | þ | %fe |
| Ÿ | %9f | Ï | %cf | ÿ | %ff |
| %a0 | Ð | %d0 | |||
| ¡ | %a1 | Ñ | %d1 | ||
| ¢ | %a2 | Ò | %d2 | ||
| £ | %a3 | Ó | %d3 | ||
| %a4 | Ô | %d4 | |||
| ¥ | %a5 | Õ | %d5 | ||
| | | %a6 | Ö | %d6 | ||
| § | %a7 | %d7 | |||
| ¨ | %a8 | Ø | %d8 | ||
| © | %a9 | Ù | %d9 | ||
| ª | %aa | Ú | %da | ||
| « | %ab | Û | %db | ||
| ¬ | %ac | Ü | %dc | ||
| ¯ | %ad | Ý | %dd | ||
| ® | %ae | Þ | %de | ||
| ¯ | %af | ß | %df | ||
| ° | %b0 | à | %e0 | ||
| ± | %b1 | á | %e1 | ||
| ² | %b2 | â | %e2 | ||
| ³ | %b3 | ã | %e3 | ||
| ´ | %b4 | ä | %e4 | ||
| µ | %b5 | å | %e5 | ||
| ¶ | %b6 | æ | %e6 | ||
| · | %b7 | ç | %e7 | ||
| ¸ | %b8 | è | %e8 | ||
| ¹ | %b9 | é | %e9 | ||
| º | %ba | ê | %ea | ||
| » | %bb | ë | %eb | ||
| ¼ | %bc | ì | %ec | ||
| ½ | %bd | í | %ed | ||
| ¾ | %be | î | %ee | ||
| ¿ | %bf | ï | %ef |
更多推荐



所有评论(0)