브라우저의 Base64 및 Node.js: 1바이트 계약, 2개의 API

브라우저에서 TextEncoder을 사용하고 Node.js에서 Buffer을 사용한 다음 동일한 유니코드 및 바이너리 픽스쳐에 대해 출력을 테스트합니다.

브라우저 클라이언트와 Node.js 서비스는 동일한 바이트에 대해 동일한 Base64을 생성해야 합니다. 이를 수행하기 위해 동일한 API을 사용할 필요는 없습니다. 중요한 합의는 텍스트의 바이트 표현, 알파벳, 패딩 처리 및 유효하지 않은 입력입니다.

브라우저: UTF-8 단계를 명시적으로 만듭니다.

기존 브라우저 기능은 바이트 문자열에서 작동합니다. 다음을 사용하여 유니코드 텍스트 변환 TextEncoder, 그런 다음 해당 바이트를 인코딩합니다. 반환 경로에서 바이트 배열을 재구성하고 UTF-8을 명시적으로 디코딩합니다. 이 예에서는 루프를 사용하여 큰 배열을 함수 인수로 확장하는 것을 방지합니다. 하지만 프로덕션 파일 인코더는 여전히 제한된 청크 또는 적절한 바이트 API을 사용해야 합니다.

const text = '中文😊';
const bytes = new TextEncoder().encode(text);
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
const encoded = btoa(binary);
console.log(encoded); // 5Lit5paH8J+Yig==
const decodedBytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const decoded = new TextDecoder('utf-8', { fatal: true }).decode(decodedBytes);
console.log(decoded); // 中文😊

Node.js: 바이트 경계에서 Buffer을 유지합니다.

Buffer.from(text, 'utf8') 텍스트 인코딩을 표시합니다. 전화 toString('base64') 그런 다음 해당 바이트를 나타냅니다. Buffer으로 디코딩하면 이진 데이터가 보존됩니다. 즉시 UTF-8 문자열로 변환하는 것은 페이로드가 텍스트로 알려진 경우에만 적합합니다.

import { Buffer } from 'node:buffer';
const encoded = Buffer.from('中文😊', 'utf8').toString('base64');
console.log(encoded); // 5Lit5paH8J+Yig==
const bytes = Buffer.from(encoded, 'base64');
console.log(new TextDecoder('utf-8', { fatal: true }).decode(bytes)); // 中文😊

예제의 치명적인 TextDecoder은 의도적인 것입니다. 일반 Buffer UTF-8 문자열 변환은 유효하지 않은 입력에 대해 대체 문자를 삽입할 수 있습니다. 성공적인 텍스트 표시는 원래 바이트가 충실하게 표시될 수 없다는 사실을 숨깁니다.

별도 검증 동의

노드의 Base64 디코더는 더 엄격한 애플리케이션에서는 거부할 수 있는 일부 입력 형식을 허용합니다. 성공적인 Buffer 변환을 프로토콜의 정식 표현이 제공되었다는 증거로 사용하지 마세요. 서명, 캐시 키 또는 상호 운용 가능한 직렬화에 대한 정확한 구문이 중요한 경우 디코딩하기 전에 확인하십시오.

공유 회귀 테스트의 경우 ASCII, 중국어, 이모티콘, 0바이트, FF 바이트 및 3바이트 경계 주변의 모든 길이를 포함합니다. 런타임 전반에 걸쳐 바이트를 비교합니다. 또한 대체 문자를 실제로 포함하는 고정 장치를 사용하여 URL-안전한 출력을 테스트하세요. 출력이 문자로만 이루어진 입력은 변형 옵션이 작동함을 증명할 수 없습니다.

Node에서 파일을 읽을 때 읽은 파일에 텍스트 인코딩을 적용하는 대신 반환된 Buffer을 유지하세요. 브라우저에서 다음을 사용하십시오. File.arrayBuffer(). 이러한 작은 경계 선택은 대부분의 우발적인 손상을 방지합니다. 참조 Node.js Buffer 노드 동작 및 MDN: btoa() 브라우저 바이트 문자열 계약의 경우.