背景

URL中某些字符具有特殊含义,比如/用于路径,?=&用于表示GET请求的参数;URL只允许ASCII字符,无法直接表示非ASCII字符,例如汉字。通常使用URL encoding来表示上述字符,形式是%{字符的十六进制UTF-8编码值}。因为有百分号%前缀,所以这种编码又称为百分号编码(Percent-encoding)。

举例:在Google搜索“python 百分号编码”,对应的URL为

https://www.google.com/search?q=python+%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81

q=之后是经过百分号编码的搜索词,其中:

  • python属于非保留字符(Unreserved Characters),保持不变;
  • 空格 被替换成加号+
  • 百分号编码属于汉字,对应的UTF-8编码为e799bee58886e58fb7e7bc96e7a081,逐字节添加%前缀得到%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81

加号

加号+在部分场景下是空格 的替代。
https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20
对于空格 ,客户端path里应该替换为%20,query里应该替换为+
服务端解析query时,会将+解析为 ,将%2B解析为+

实现

Python

>>> import urllib.parse as pa
>>> pa.quote_plus("python 百分号编码")
'python+%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81'

JavaScript

For application/x-www-form-urlencoded, spaces are to be replaced by +, so one may wish to follow a encodeURIComponent() replacement with an additional replacement of %20 with +.

>>> encodeURIComponent("JS 百分号编码")
>>> 'JS%20%E7%99%BE%E5%88%86%E5%8F%B7%E7%BC%96%E7%A0%81'

参考资料

https://en.wikipedia.org/wiki/Percent-encoding
https://docs.python.org/3/library/urllib.parse.html#urllib.parse.quote_plus
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent