URL编码

简介: 通过这篇文章,你可以了解到:1、为什么要有 URL 编码2、URL 编码的规则

介绍 URL 编码

URL 编码也被称为百分号编码。

URL 编码的规则:简单来说,如果需要对一个字符进行 URL 编码,首先需要判断该字符是否是 ASCII 字符:

  • 如果一个字符是 ASCII 字符,那么对该字符进行 URL 编码,首先需要把该字符的 ASCII 的值表示为两个 16 进制的数字,然后在其前面放置转义字符 %,就得到了该字符的 URL 编码结果。
  • 如果一个字符是非 ASCII 字符,那么对该字符进行 URL 编码,首先需要使用指定的字符编码方式(建议使用 UTF-8 字符编码),将 “非 ASCII 字符” 编码为字节序列(字节序列即二进制数据);然后对其字节序列进行 URL 编码。URL 编码 “二进制数据”,首先需要把 “二进制数据” 表示为 8 位组的序列,然后在每个 8 位组的前面放置转义字符 %,就得到了 “二进制数据” 的 URL 编码结果。

技术是为了解决问题而生的,URL 编码的作用是:使用 “安全的字符”(允许出现的字符、无歧义的字符) 替换 “不安全的字符”(不允许出现的字符、有歧义的字符)

  • 将 “非 ASCII 字符” 编码为 “ASCII 字符”,便于在 URL 中传输非 ASCII 字符。(URL 中只能出现 ASCII 字符,不能出现非 ASCII 字符)
  • 将 “空格” 编码为 “%20”,便于在 URL 中传输空格。(URL 中不能出现空格)
  • 将 “没有表示特殊含义的保留字符” 进行 URL 编码。(URL 中多个查询参数之间用 & 符号分隔。如果参数值中包含了 & 字符,那么会对 URL 解析造成影响,因此需要对造成歧义的 & 符号进行编码)

URL 编码的规则

URL 编码需要遵循 RFC 3986 标准。RFC 3986: Uniform Resource Identifier (URI): Generic Syntax (rfc-editor.org)

RFC3986 协议规定 URL 只允许包含两类字符:“保留字符” 和 “未保留字符”。“保留字符” 和 “未保留字符” 都属于是 ASCII 字符。

  • 保留字符:“保留字符” 是那些具有特殊含义的字符,比如:斜线字符 / 用于 URL 不同部分的分界。常见的 “保留字符” 有:冒号 :(分隔协议 和 主机)、斜线 /(分隔主机 和 路径)、问号 ?(分隔路径 和 查询参数)、等于号 =(分隔参数 和 参数值)、and 符号 &(分隔多个查询参数)
  • 未保留字符:“未保留字符” 没有那些特殊的含义。“未保留字符” 有:大小写字母 a - z、阿拉伯数字 0 - 9、连字号 - 、下划线 _ 、句号 . 、波浪号 ~

对 “保留字符” 进行 URL 编码:如果一个 “保留字符” 在特定上下文中具有特殊含义,并且 URL 中必须使用该 “保留字符” 用于其它目的,那么必须对不表示特殊含义的 “保留字符” 进行 URL 编码。(比如,斜线字符 / 用于 URL 不同部分的分界,但是斜线字符 / 又需要出现在 URL 一个路径成分的内部)

URL 编码一个 “保留字符”,首先需要把该 “保留字符” 的 ASCII 的值表示为两个 16 进制的数字,然后在其前面放置转义字符 %,置入 URL 中的相应位置。(比如,URL 编码斜线字符 /,斜线字符 / 的 ASCII 的值为 47,10 进制的 47 等于 16进制的 2F,因此斜线字符 / 经过 URL 编码后为 %2F)


对 “未保留字符” 进行 URL 编码: “未保留字符” 不需要进行 URL 编码。如果两个 URL 的差别仅在于 “未保留字符” 是用 URL 编码还是用字符自身表示,那么这两个 URL 具有等价的语义。


对 “百分号 %” 进行 URL 编码:由于 “百分号 %” 用于 URL 编码,因此用于 URL 内部的 “百分号 %” 应该被编码。 “百分号 %” 的 URL 编码结果为 "%25"。


对任意数据进行 URL 编码:

  • 对 “二进制数据” 进行 URL 编码:URL 编码 “二进制数据”,首先需要把 “二进制数据” 表示为 8 位组的序列(8 位组的序列是将二进制数据按 8 位分组),然后将每个 8 位组表示为两个 16 进制的数字,然后在其前面放置转义字符 %,就得到了 “二进制数据” 的 URL 编码结果。
  • 对 “非 ASCII 字符” 进行 URL 编码:URL 编码一个 “非 ASCII 字符”,首先需要使用指定的字符编码方式(建议使用 UTF-8 字符编码),将 “非 ASCII 字符” 编码为字节序列(字节序列即二进制数据);然后对其字节序列进行 URL 编码。

encodeURI 和 encodeURIComponent 方法

encodeURI() 和 encodeURIComponent() 这两个方法是 JavaScript 中进行 URL 编码的方法。


介绍 encodeURI() 方法:

  • encodeURI() 方法编码的字符范围:非 ASCII 字符、保留字符的小部分,包括 [] 不包括 !#$&'()*+,/:;=?@
  • encodeURI() 方法解码使用 decodeURI() 方法

介绍 encodeURIComponent() 方法:

  • encodeURIComponent() 方法编码的字符范围:非 ASCII 字符、保留字符的大部分,包括 #$&+,/:;=?@[] 不包括 !'()*
  • 可见 encodeURIComponent 比 encodeURI 编码的范围更广。因此当你需要编码整个 URL 就使用 encodeURI;当你只需要编码 URL 中的参数时,就使用 encodeURIComponent
  • encodeURIComponent() 方法解码使用 decodeURIComponent() 方法

application/x-www-form-urlencoded

https://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

当 HTML 表单中的数据被提交时,表单的域名与值被编码并通过网络把数据发送给服务器。这里的编码方法采用了一个非常早期的通用的 URL 编码方法,并且有很多小的修改,如换行规范化 以及 把空格符的编码 "%20" 替换为 "+"。按这套方法编码的数据的 MIME 类型是 application/x-www-form-urlencoded,当前仍用于 HTML 与 XForms 规范中。

如果发送的是 HTTP GET 请求,application/x-www-form-urlencoded 数据包含在所请求 URL 的查询参数中。如果发送的是 HTTP POST 请求,数据被放置在请求主体中,媒体类型的名字被包含在 Content-Type 请求首部字段。

URL 编码的注意事项

Java 中的 URLEncoder.encode() 方法把 “空格符” 编码为"+",而不是 "%20"。

如果我们把带空格的字符串的编码结果发送给前端。前端调用 decodeURIComponent() 解码时,加号 + 将无法解码为空格。

// encode = say+hello
String encode = URLEncoder.encode("say hello", Charset.defaultCharset().displayName());

解决方案:

  • 对 URL 编码结果,调用 String 的 replace(),将 + 号替换为 %20
  • 使用其他的 URL 编码工具:可以使用 Spring 提供的 UriUtils 来代替 URLEncoder(推荐使用)

参考资料

百分号编码 - 维基百科,自由的百科全书 (wikipedia.org)

相关文章
|
2月前
|
Java
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
93 4
|
5月前
|
JavaScript 前端开发 数据格式
URL编码【详解】——Javascript对URL进行编码解码的三种方式的区别和使用场景,axios请求拦截器中对get请求的参数全部进行URL编码
URL编码【详解】——Javascript对URL进行编码解码的三种方式的区别和使用场景,axios请求拦截器中对get请求的参数全部进行URL编码
306 0
|
6月前
|
安全 JavaScript PHP
URL百分号编码
URL百分号编码
|
7月前
|
Java
dk1.8和jdk17底层对url参数的编码不一样吗
dk1.8和jdk17底层对url参数的编码不一样吗
107 0
|
7月前
|
JavaScript
URL编码中的escape、encodeURI和encodeURIComponent
URL编码中的escape、encodeURI和encodeURIComponent
197 1
|
7月前
|
数据安全/隐私保护
URL编码解析方式-特殊字符加密和解密
URL编码解析方式-特殊字符加密和解密
131 0
|
JavaScript 前端开发
JS实现url的编码和解码
JS实现url的编码和解码
117 1
|
7月前
|
Python
Python-URL编码和URL解码方法
Python-URL编码和URL解码方法
128 0
|
7月前
|
存储 Web App开发 JavaScript
Unicode、UTF 和 ISO-8859-1等编码方式详解与浏览器URL编码
Unicode、UTF 和 ISO-8859-1等编码方式详解与浏览器URL编码
811 0
a标签下载特殊字符url手动编码浏览器兼容性不显示
a标签下载特殊字符url手动编码浏览器兼容性不显示