atob、btoa 和 encodeURIComponent

在前后端数据传输过程中,atobbtoaencodeURIComponent 是常用的编码工具,分别用于不同场景,以下是它们的特点和适用情况:


1. atobbtoa

  • btoa(binary-to-ASCII)函数的作用是将一个ASCII 字符串编码成 Base64 字符串

  • ASCII 字符串指的是仅包含 ASCII 编码字符的字符串,这些字符的编码值在 0 到 127 范围内。

  • btoa 只支持 ASCII 字符,因此如果字符串包含非 ASCII 字符(如中文或表情符号等),则需要先将其转换为符合 ASCII 字符集的格式(通常通过encodeURIComponent 或其他编码方式)。

  • atob(ASCII-to-binary)函数的作用是将一个 Base64 编码的字符串 解码为原始的 ASCII 字符串。

  • 这个过程是将 Base64 编码的数据转回成它的原始文本表示形式,通常是一个包含 ASCII 字符的字符串。

  • encodeURIComponent 会将非 ASCII 字符(如中文、表情符号)和部分特殊字符编码成 % 开头的 百分比编码(最终还是ASCII 字符串!!!!!)


  • 功能

    • atob:将 Base64 编码的字符串解码为原始的ASCII 字符串。
    • btoa:将ASCII 字符串编码为 Base64 字符串。
  • 适用场景

    • 处理二进制数据(如图像、文件)以适应基于文本传输的协议(如 HTTP)。
    • 在前后端之间传递较小的二进制数据或加密数据。
  • 注意事项

    • 不支持 Unicode 字符,直接处理非 ASCII 字符会导致乱码。
    • 对于非 ASCII 数据,需要先通过编码处理后再使用 btoa

2. encodeURIComponent

  • 功能

    • 对字符串进行 URI 编码,将特殊字符(如 @, /, ?, = 等)转义为 %XX 格式,以便在 URL 中安全传递。
    • 简单来说,encodeURIComponent 会将非 ASCII 字符(如中文、表情符号)和部分特殊字符编码成 % 开头的 百分比编码(确保所有字符都是ASCII,之后才能用 btoa 编码
  • 适用场景

    • URL 参数编码,确保数据在 HTTP 请求中不会因特殊字符而破坏格式。
    • 在查询字符串或路径中传递包含特殊字符的参数。
  • 注意事项

    • 不编码通用的 URI 保留字符(如 :/ 等)。
    • 用于处理前后端通过 URL 或 Query 参数传递的内容。
  • 示例

    const param = 'Hello, World!';
    const encoded = encodeURIComponent(param);
    console.log(encoded); // 输出:Hello%2C%20World%21
    
    // 解码
    const decoded = decodeURIComponent(encoded);
    console.log(decoded); // 输出:Hello, World!
    

前后端传输过程中的配合

  1. Base64(btoa / atob

    • 用于编码和解码较小的 ASCII 字符串数据或特定的文本数据。
    • 示例:
      • 前端使用 btoa 编码文件内容。
      • 后端收到数据后通过语言相应的 Base64 解码工具(如 Buffer.from)解析。
  2. URL 参数(encodeURIComponent

    • 确保通过 URL 传递的字符串不会因特殊字符而导致问题。
    • 示例:
      • 前端通过 encodeURIComponent 对字符串进行编码。
      • 后端使用对应的解码工具(如 decodeURIComponent)还原数据。
  3. 二者结合

    • 对需要通过 URL 传递的 Base64 字符串,先用 btoa 编码,再用 encodeURIComponent 进一步转义。
    • 示例:
      const data = btoa('Sensitive data!');
      const safeData = encodeURIComponent(data); // 用于安全的 URL 传递
      

注意的编码问题

  • 如果需要处理 Unicode 数据(如中文):
    • 在 Base64 编码时,需先将其转换为 UTF-8 字符串。
    • 使用 TextEncoderTextDecoder 辅助:
      const utf8ToBase64 = (str) =>
        btoa(String.fromCharCode(...new TextEncoder().encode(str)));
      const base64ToUtf8 = (base64) =>
        new TextDecoder().decode(Uint8Array.from(atob(base64), (c) => c.charCodeAt(0)));
      
      const data = '你好,世界';
      const base64 = utf8ToBase64(data);
      console.log(base64); // Base64 编码后的字符串
      
      const original = base64ToUtf8(base64);
      console.log(original); // 解码后的原始字符串
      

为什么不直接使用 encodeURIComponent 处理中文到 Base64?


总结:

  • 使用 btoaatob 处理ASCII数据的文本传输。
  • 使用 encodeURIComponent 处理 URL 参数传递。
  • 根据具体场景选择合适的工具,确保数据在前后端传输中的完整性与安全性。

下面是由于未编码传输 URL 可能被破坏的情况:

URL 可能被破坏的情况是由于未对特殊字符(如 &, ?, = 等)进行正确的转义或编码,导致 URL 被错误解析,进而导致参数丢失或数据不正确。

URL 被破坏的原因

  • 特殊字符冲突:URL 的参数通常通过 & 分隔,值由 = 分配。如果参数值中包含这些符号而未编码,浏览器或服务器会将其误解为新的参数。
  • 未编码的非 ASCII 字符:如果 URL 中包含中文或其他非 ASCII 字符,未正确编码时可能导致无法正确解析。

示例 1:未转义特殊字符导致解析错误

假设我们需要通过 URL 传递以下数据:

{
  "user": "张三",
  "message": "Hello & welcome!"
}
错误实现
const user = "张三";
const message = "Hello & welcome!";
const url = `https://example.com?user=${user}&message=${message}`;
console.log(url); 

生成的 URL:

https://example.com?user=张三&message=Hello & welcome!
问题
  1. & 被误解为新参数分隔符,welcome! 被丢失。
  2. 中文 张三 未编码,某些浏览器或服务器可能无法正确解析。

正确实现

使用 encodeURIComponent 对参数进行编码:

const user = encodeURIComponent("张三");
const message = encodeURIComponent("Hello & welcome!");
const url = `https://example.com?user=${user}&message=${message}`;
console.log(url); 

生成的 URL:

https://example.com?user=%E5%BC%A0%E4%B8%89&message=Hello%20%26%20welcome%21
效果
  • & 被编码为 %26,不会被解析为分隔符。
  • 中文 张三 被编码为 %E5%BC%A0%E4%B8%89,确保兼容性。

示例 2:Base64 数据未编码导致解析错误

假设我们传递 Base64 编码的文件内容:

const fileContent = btoa("Hello, World!");
const url = `https://example.com?file=${fileContent}`;
console.log(url);

生成的 URL:

https://example.com?file=SGVsbG8sIFdvcmxkIQ==
问题
  1. Base64 中的 = 是 URL 中的保留字符,可能导致解析错误或数据丢失。
  2. 若 Base64 数据中包含 /+,也可能干扰路径解析或被替换。

正确实现

使用 encodeURIComponent 对 Base64 数据进行编码:

const fileContent = encodeURIComponent(btoa("Hello, World!"));
const url = `https://example.com?file=${fileContent}`;
console.log(url);

生成的 URL:

https://example.com?file=SGVsbG8sIFdvcmxkIQ%3D%3D
效果
  • = 被编码为 %3D,避免误解为参数分隔符。
  • 保证 Base64 数据在 URL 中传输的完整性。

示例 3:JSON 数据未编码导致解析错误

假设需要通过 URL 传递 JSON 数据:

{
  "name": "张三",
  "message": "Hello, 世界!",
  "emoji": "😊"
}
错误实现
const json = JSON.stringify({ name: "张三", message: "Hello, 世界!", emoji: "😊" });
const url = `https://example.com?data=${json}`;
console.log(url);

生成的 URL:

https://example.com?data={"name":"张三","message":"Hello, 世界!","emoji":"😊"}
问题
  1. {} 未编码,可能被误解为路径或格式错误。
  2. 中文 张三 和表情符号 😊 未编码,某些环境下可能解析失败。

正确实现

使用 btoaencodeURIComponent 组合:

const json = JSON.stringify({ name: "张三", message: "Hello, 世界!", emoji: "😊" });
const encodedData = encodeURIComponent(btoa(unescape(encodeURIComponent(json))));
const url = `https://example.com?data=${encodedData}`;
console.log(url);

生成的 URL:

https://example.com?data=eyJuYW1lIjoiJUU1JUJCJUEzJUU0JUJEJUEwIiwibWVzc2FnZSI6IkhlbGxvLCAlRTQlQjglQjAlRTUlQkMlODAhIiwiZW1vamkiOiLwn5iKIn0%3D
效果
  • 所有特殊字符被安全编码。
  • JSON 数据可以无损传输。

总结

使用 btoaencodeURIComponent 可以避免以下 URL 被破坏的常见问题:

  1. 特殊字符干扰:如 &, =, ? 等未正确编码会导致解析错误。
  2. 非 ASCII 字符:中文、表情符号等未编码可能导致丢失或乱码。
  3. 数据完整性:Base64 中的 =, /, + 等字符会干扰 URL 解析,需额外处理。

通过结合 btoaencodeURIComponent,可以确保数据在 URL 中传输时的完整性和安全性,避免被错误解析或丢失。

JavaScript 中的 `window.atob()` 方法用于对经过 base - 64 编码的字符串进行解码。 ### 功能 `window.atob()` 方法的主要功能是将 base - 64 编码的字符串解码为原始字符串。可以使用 `window.btoa()` 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 `window.atob()` 方法再将数据解码,例如可以对各种字符,像 0 - 31 的 ASCII 码值进行编码、传输解码操作 [^2]。 ### 使用方法 以下是 `window.atob()` 方法的使用示例: ```javascript // 定义一个待编码的字符串 var str = "RUNOOB"; // 使用 window.btoa() 方法进行编码 var enc = window.btoa(str); // 使用 window.atob() 方法对编码后的字符串进行解码 var dec = window.atob(enc); // 输出编码解码后的结果 var res = "编码字符串为: " + enc + "<br>" + "解码后字符串为: " + dec; console.log(res); ``` 在上述代码中,首先使用 `window.btoa()` 方法对字符串 `"RUNOOB"` 进行编码,得到编码后的字符串 `enc`,然后使用 `window.atob()` 方法对 `enc` 进行解码,得到原始字符串 `dec`。 ### 注意事项 - **输入格式**:`window.atob()` 方法的输入必须是有效的 base - 64 编码字符串。如果输入的字符串未正确编码,会抛出错误,如 “无法在 'Window' 上执行 'atob':要解码的字符串未正确编码” [^3]。 - **Unicode 字符串处理**:由于历史原因,`window.atob()` `window.btoa()` 函数的输入输出都是 Unicode 字符串。对于包含非 ASCII 字符(如中文)的字符串,不能直接使用 `window.btoa()` 进行编码,需要先将其转换为 URL 组件格式,再进行编码。例如: ```javascript // 先将中文转换为 URL 组件格式,再转为 base64 形式 var d = btoa(encodeURIComponent("哈哈")); // 解码时先使用 atob() 解码,再使用 decodeURIComponent() 还原 var original = decodeURIComponent(atob(d)); console.log(original); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值