Rumah  >  Artikel  >  hujung hadapan web  >  Bagaimanakah anda menyahkod rentetan UTF-8 base64 dalam JavaScript menggunakan `atob` sambil mengelakkan ralat pengekodan?

Bagaimanakah anda menyahkod rentetan UTF-8 base64 dalam JavaScript menggunakan `atob` sambil mengelakkan ralat pengekodan?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-10-31 21:08:291000semak imbas

How do you decode UTF-8 base64 strings in JavaScript using `atob` while avoiding encoding errors?

Menggunakan atob untuk menyahkod base64 daripada sumber teks biasa

Apabila menggunakan atob untuk menyahkod rentetan respons API daripada perkhidmatan yang menjana outputnya dalam UTF-8, anda mungkin menghadapi ralat atau pengekodan rentetan yang rosak. Ini disebabkan oleh pengehadan pengendalian base64 JavaScript:

<code class="js">const notOK = "✓"
console.log(btoa(notOK)); // error</code>

Masalah Unikod

Walaupun selepas ralat ini diselesaikan dalam ECMAScript, "Masalah Unicode" kekal, kerana base64 ialah binari format yang menganggap setiap aksara yang dikodkan menduduki satu bait. Banyak aksara Unicode memerlukan lebih daripada satu bait untuk mengekod, yang boleh menyebabkan kegagalan pengekodan.

Sumber: MDN (2021)

<code class="js">const ok = "a";
console.log(ok.codePointAt(0).toString(16)); // 0x61: occupies 1 byte

const notOK = "✓";
console.log(notOK.codePointAt(0).toString(16)); // 0x2713: occupies 2 bytes</code>

Penyelesaian dengan kebolehoperasian binari

Jika anda tidak pasti penyelesaian yang mana untuk dipilih, ini mungkin penyelesaian yang anda mahukan. Teruskan menatal untuk penyelesaian ASCII base64 dan sejarah jawapan ini.

Pertimbangkan menggunakan pendekatan binari dengan menukar rentetan UTF-8 kepada perwakilan binari dan sebaliknya.

Pengekodan UTF-8 ⇢ binari

<code class="js">function toBinary(string) {
  const codeUnits = new Uint16Array(string.length);
  for (let i = 0; i < codeUnits.length; i++) {
    codeUnits[i] = string.charCodeAt(i);
  }
  return btoa(String.fromCharCode(...new Uint8Array(codeUnits.buffer)));
}
encoded = toBinary("✓ à la mode") // "EycgAOAAIABsAGEAIABtAG8AZABlAA=="</code>

Menyahkod binari ⇢ UTF-8

<code class="js">function fromBinary(encoded) {
  const binary = atob(encoded);
  const bytes = new Uint8Array(binary.length);
  for (let i = 0; i < bytes.length; i++) {
    bytes[i] = binary.charCodeAt(i);
  }
  return String.fromCharCode(...new Uint16Array(bytes.buffer));
}
decoded = fromBinary(encoded) // "✓ à la mode"</code>

Penyelesaian dengan kebolehoperasian ASCII base64

Untuk mengekalkan kefungsian UTF-8, pendekatan lain melalui kebolehoperasian ASCII base64 disyorkan, yang membetulkan "Masalah Unikod" sambil mengekalkan keserasian dengan rentetan base64 berasaskan teks.

Pengekodan UTF-8 ⇢ ASCII base64

<code class="js">function b64EncodeUnicode(str) {
    // Percent-encode Unicode, then convert to byte array
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
        function(match, p1) {
            return String.fromCharCode('0x' + p1);
    }));
}
b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="</code>

Menyahkod ASCII base64 ⇢ UTF-8

<code class="js">function b64DecodeUnicode(str) {
    // Convert byte array to percent-encoding, then decode
    return decodeURIComponent(atob(str).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));
}
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"</code>

Sokongan TypeScript

<code class="ts">function b64EncodeUnicode(str) {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
        return String.fromCharCode(parseInt(p1, 16))
    }))
}
function b64DecodeUnicode(str) {
    return decodeURIComponent(Array.prototype.map.call(atob(str), function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    }).join(''))
}</code>

Nota Tambahan

  • White penyingkiran ruang mungkin diperlukan untuk menyahkod rentetan base64 daripada sumber seperti API GitHub pada Safari.
  • Perpustakaan seperti js-base64 dan base64-js juga menyediakan penyelesaian yang boleh dipercayai.

Atas ialah kandungan terperinci Bagaimanakah anda menyahkod rentetan UTF-8 base64 dalam JavaScript menggunakan `atob` sambil mengelakkan ralat pengekodan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn