常用ASCII URL编码对照表,JavaScript中如何把url的%20、%22、%28、%29、%7B、%7D解析还原成真实的字符

【问题描述】:

笔者遇到过这样一个需求,在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
  }
【重点知识】:
  1. 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    

你可能感兴趣的:(HTML,ascii码表,编码)