12、URL 编解码

一、为什么要 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;

/**
 * URL 编码解码
 * @author zhangxw
 * @since 0.0.1
 */
public class URLDecoderTest {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "张兴旺zxw";

		// URLDecoder:URL 解码。
		String encodeStr = URLEncoder.encode(str, "GBK");

		// %D5%C5%D0%CB%CD%FAzxw
		System.out.println(encodeStr);

		// URLDecoder:URL 解码。
		// 张兴旺zxw
		System.out.println(URLDecoder.decode(encodeStr, "GBK"));


	// URLEncoder.encode 的原理:
		// 第 1 步:获取字符串 对应编码的 byte 数组。
		byte[] bytes = str.getBytes("GBK");

		// GBK 编码结果:"张兴旺zxw" → 字节数组:[-43, -59, -48, -53, -51, -6, 122, 120, 119]
		System.out.println(Arrays.toString(bytes));

		StringBuilder hexBuilder = new StringBuilder();
		// 第 2 步:将 字节数组:[-43, -59, -48, -53, -51, -6, 122, 120, 119] 中的每个 byte 数字,
			// 转为 【无符号的十六进制】字符串。
		for (byte b : bytes) {
			// 消除符号位影响
			int value = b & 0xFF;
			hexBuilder.append(String.format("%02X ", value));
		}
		// 无符号十六进制: D5 C5 D0 CB CD FA 7A 78 77
		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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值