美文网首页
URI Encoding

URI Encoding

作者: 张培_ | 来源:发表于2020-03-31 21:28 被阅读0次

What is URL Encoding

URL Encoding 也被成为 percent encoding,URL是由有限的字符(来自US-ASCII character set)组成的,这些字符包含数字(0-9)、字幕(a-z, A-Z)、特殊字符- _ . ~

这也就意味着,URL中不能包含:

  • ASCII控制字符(退格键,垂直制表符,水平制表符,换行符等)
  • unsafe characters: space、\、<>、{、}
  • 不在ASCII中的字符

还有一些绝对不能出现在query中的字符:

  • 常见的一些对于URL有特殊意义的字符,被称作保留字符。比如: / # ? :

那么,当你的URI中必须要包含一些不被允许的字符该怎么办呢?

这时候就需要使用URL Encoding将不被允许的字符转换成对应的十六进制三元字符组, 这个转换的过程被称为URI的encoding。

URI encode也被称作percent-encoding, 原因是,所有不被允许的字符都需要转义成为使用%开头的十六进制字符组,因此也被叫做perceng encoding

哪些字符可以包含在URI中?

根据RFC 3986所述,一个valid的URI中只能包含以下84种字符:

  • 特殊字符
-._~:/?#[]@!$&'()*+,;=
  • 字母
    a-z / A-Z

  • 数字
    0-9

  • 以%开头的十六进制三元字符组

除此之外的任何一种字符都需要是使用字符三元组替代。

如果URL中出现这种不被允许的字符会怎么样呢?

  • 请求通过浏览器或者postman,做过转义之后发出

如果你通过浏览器发出请求中包含了一些不被允许的字符,浏览器会帮助我们做一些转义,别以为这是一件好事儿,因为不同的浏览器有不同的转义字符的方式。这时候你可能会惊喜的发现,同样一个URL,chrome上请求成功,IE11直接400

  • 请求不做任何转义直接发送到server

这种方式我也不知道如何做到,我尝试使用curl/postman/发现都会被转义,那么我们就大胆的猜测一下。

一个真的没有转义过包含非法字符的请求发送到server,会出现什么结果呢?

大胆猜测一下,server应该没有办法resolve这种请求,那么就有可能直接throw 400 error


简而言之, 如果直接发送包含不允许字符的URI给server,同样Server也不能够识别这些字符,就有可能导致这次请求失败

How can we achieve URL encoding in JS

JS提供了内置了两个API对URI进行encode:

  • encodeURIComponent
  • encodeURI

他们都可以将特殊字符进行encode,那么区别是什么呢?

  • encodeURI() 不会encode: ~!@#$&*()=:/,;?+'

说明这个function可以作用于整个URI

encodeURI('https://stackoverflow.com/questions/?path={"a":"1"}')

// "https://stackoverflow.com/questions/?path=%7B%22a%22:%221%22%7D"
  • encodeURIComponent() will not encode: ~!*()'

说明类似于?这种分界query和path的符号也会被转义,因此无法作用于整个URI

encodeURIComponent是对URI的组成部分进行编码的方法,而不用对整个URL进行编码。

encodeURIComponent('https://stackoverflow.com/questions/?path={"a":"1"}')

// "https%3A%2F%2Fstackoverflow.com%2F%3Fpath%3D%7B%22a%22%3A%221%22%7D"

这样的URL根本无法被识别

Note

请不要使用escape,此方法已经被废弃

实例

  • 在client端发一个请求获取所有的search result, 我在code中直接使用了fetch给下面的url发送了请求
https://xxxx/AAA/api/results?info={
"name":"yoyo"}&options={"page":1,"pageSize":30}
  • 当我在chrome中打开页面的时候,server端接收到的请求是:
https://xxxx/AAA/api/results?info={%22name%22:%22yoyo%22}&options={%22page%22:1,%22pageSize%22:30}
  • 当我在IE11中打开页面的时候,发现这个请求总是400,结果查看server端接收到的请求是:
https://xxxx/AAA/api/results?info={\x22name\x22:\x22yoyo\x22}&options={\x22page\x22:1,\x22pageSize\x22:30}

由于window的编码方式不同,导致server端无法识别\x22,所以直接返回400

相关文章

网友评论

      本文标题:URI Encoding

      本文链接:https://www.haomeiwen.com/subject/mmaguhtx.html