一、为什么要 URL 编码
- 在因特网上传送 URL,只能采用 ASCII 字符集。
- 1、只有字母和数字 [0-9a-zA-Z]、一些特殊符号 $-_.+!*'() [不包括双引号]、以及某些保留字(空格转换为+),才可以不经过编码直接用于 URL。
- 2、如果 URL 中有汉字,就必须编码后使用。 但是麻烦的是标准的国际组织并没有规定具体的编码方法,而是交给应用程序(浏览器)自己决定。 这导致"URL编码"成为了一个混乱的领域。
- 3、对于同一个中文,不同的浏览器可能会有不同的编码方式,不要将编码交给浏览器。应该用 JS 在前端对 URL 编码,这样就实现了统一。
- 如果 key=value 这种传参方式中,value 中包含 ?``=& 等符号,url 的解析会变得很困难。
二、什么是 URL 编码
- 1、URL 编码通常也被称为百分号编码(percent-encoding),是因为它的编码方式非常简单:
- 1、使用 % 加上两位的字符——0123456789ABCDEF——代表一个字节的十六进制形式。
- 2、URL 编码要做的,就是将每一个非安全的 ASCII 字符都被替换为“%xx”格式,
- 2、对于 非 ASCII 字符,的 URL 编码实现,RFC 文档建议:
- 1、使用 utf-8 对其进行编码得到相应的字节。
- 如:"中文"使用 UTF-8 编码 得到的字节为 0xE4 0xB8 0xAD 0xE6 0x96 0x87。
- 2、然后,对每个字节执行百分号编码。
- 如:0xE4 0xB8 0xAD 0xE6 0x96 0x87 经过 Url 编码后得到 “%E4%B8%AD%E6%96%87”。
三、JS 的三种 URL 编码
- 1、escape
- 2、encodeURI 函数 (推荐使用)
- 1、对需要编码的参数用 encodeURI 函数最推荐
- 2、对应的解码函数是 decodeURI()
- 3、encodeURIComponent函数(最推荐使用)
- 1、对需要编码的参数用 encodeURIComponent 函数最推荐
- 2、对应的解码函数是 decodeURIComponent()
四、Java 中的 URL 编码、解码 – URLDecoder 与 URLEncoder
- URLEncoder:可以把非西欧文字 “张三zxw” 编码成 “%E5%BC%A0%E4%B8%89zxw” 的形式。
- –在有些场景,无法传输和存储“非西欧文字”,此时就需要用到 URLEncoder 转换。
- 典型的像 Cookie,Cookie 的值不能使中文的。
- URLDecoder:可以把 “%E5%BC%A0%E4%B8%89zxw” 的形式解码成 “张三zxw”。
- URLEncoder 的核心逻辑是:
- 将每个字节视为无符号的 8 位整数(0-255),然后转为 %XX 格式的十六进制字符串。
- 具体步骤:
- 将 byte 转换为 int,并屏蔽符号位(通过 & 0xFF)。
- 将结果转为两位十六进制字符串。如:0xE4 → %E4。
package org.rainlotus.materials.javabase.a01_unicode;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
public class URLDecoderTest {
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "张兴旺zxw";
String encodeStr = URLEncoder.encode(str, "GBK");
System.out.println(encodeStr);
System.out.println(URLDecoder.decode(encodeStr, "GBK"));
byte[] bytes = str.getBytes("GBK");
System.out.println(Arrays.toString(bytes));
StringBuilder hexBuilder = new StringBuilder();
for (byte b : bytes) {
int value = b & 0xFF;
hexBuilder.append(String.format("%02X ", value));
}
System.out.println("无符号十六进制: " + hexBuilder);
}
}
五、什么是 application/x-www-form-urlencoded
- 1、是一种编码类型。
- 当 URL 地址里包含 非西欧字符 的字符串时,
- 系统会将这些字符转换成 application/x-www-form-urlencoded 字符串。
- 表单提交中的表单里包含 非西欧字符 的字符串时,
- 系统也会将这些字符转换成 application/x-www-form-urlencoded 字符串,
- 然后,在服务器端自动解码。
- FORM 元素的 enctype 属性指定了表单数据向服务器提交时所采用的编码类型,
- 默认的缺省值是 application/x-www-form-urlencoded。
- 2、在向服务器发送大量的文本、包含大量非 ASCII 字符的文本或二进制数据时这种编码方式效率很低。
- 这时,就要使用另一种编码类型“multipart/form-data”。
- 如:做文件上传时,表单的 enctype 属性一般会设置成“multipart/form-data”。
- Browser 端 表单的 ENCTYPE 属性值为 multipart/form-data 。
- 它告诉我们传输的数据要用到多媒体传输协议,由于多媒体传输的都是大量的数据。
- 所以,规定上传文件必须是 post 方法,<input> 的 type 属性必须是 file。