>  기사  >  웹 프론트엔드  >  인코딩 오류를 피하면서 'atob'을 사용하여 JavaScript에서 UTF-8 base64 문자열을 어떻게 디코딩합니까?

인코딩 오류를 피하면서 'atob'을 사용하여 JavaScript에서 UTF-8 base64 문자열을 어떻게 디코딩합니까?

Mary-Kate Olsen
Mary-Kate Olsen원래의
2024-10-31 21:08:291000검색

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

atob을 사용하여 일반 텍스트 소스에서 base64 디코딩

atob을 사용하여 UTF-8로 출력을 생성하는 서비스에서 API 응답 문자열을 디코딩하는 경우 오류가 발생할 수 있습니다. 또는 깨진 문자열 인코딩. 이는 JavaScript의 base64 처리 제한 때문입니다.

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

유니코드 문제

ECMAScript에서 이 오류가 해결된 후에도 base64는 바이너리이므로 "유니코드 문제"가 남아 있습니다. 각 인코딩된 문자가 단일 바이트를 차지한다고 가정하는 형식입니다. 많은 유니코드 문자는 인코딩하는 데 1바이트 이상이 필요하므로 인코딩 실패로 이어질 수 있습니다.

출처: 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>

바이너리 상호 운용성을 갖춘 솔루션

어떤 솔루션을 선택해야 할지 확신이 없다면 아마도 이것이 여러분이 원하는 솔루션일 것입니다. ASCII base64 솔루션과 이 답변의 기록을 보려면 계속 스크롤하세요.

UTF-8 문자열을 이진 표현으로 또는 그 반대로 변환하여 이진 접근 방식을 사용하는 것을 고려하세요.

인코딩 UTF-8 ⇢ 바이너리

<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>

바이너리 디코딩 ⇢ 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>

ASCII base64 상호 운용성을 갖춘 솔루션

UTF-8 기능을 유지하려면 다음을 통한 또 다른 접근 방식을 사용하세요. 텍스트 기반 base64 문자열과의 호환성을 유지하면서 "유니코드 문제"를 해결하는 ASCII base64 상호 운용성을 권장합니다.

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>

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>

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>

추가 참고 사항

  • GitHub API와 같은 소스에서 base64 문자열을 디코딩하려면 공백 제거가 필요할 수 있습니다. Safari.
  • js-base64 및 base64-js와 같은 라이브러리도 안정적인 솔루션을 제공합니다.

위 내용은 인코딩 오류를 피하면서 'atob'을 사용하여 JavaScript에서 UTF-8 base64 문자열을 어떻게 디코딩합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.