JavaScript Base64 JSON, 파일 및 바이트 배열에 대한 레시피

실수로 바이너리 데이터를 텍스트로 처리하지 않고 JSON 페이로드 및 선택한 파일에 대한 UTF-8-안전한 JavaScript 레시피를 사용하세요.

유용한 Base64 코드는 실제로 입력이 무엇인지 결정하는 것부터 시작합니다. JavaScript 문자열에는 문자 인코딩이 필요합니다. 파일에 이미 바이트가 있습니다. JSON 값은 먼저 직렬화가 필요합니다. 이러한 단계를 표시하면 디버깅이 더 쉬워지고 실수로 인한 이중 인코딩을 방지할 수 있습니다.

작은 JSON 값을 인코딩합니다.

값을 정확히 한 번 직렬화하고 해당 문자열을 UTF-8로 인코딩한 다음 바이트를 Base64로 인코딩합니다. 이 예에는 영어로만 작동하는 구현을 포착하기 위한 비 ASCII 필드가 포함되어 있습니다. 이는 작은 페이로드를 위한 것입니다. 임시 바이트 문자열은 메모리 사용량을 증가시킵니다.

const value = { message: '你好', count: 3 };
const text = JSON.stringify(value);
let binary = '';
for (const byte of new TextEncoder().encode(text)) {
  binary += String.fromCharCode(byte);
}
const encoded = btoa(binary);
const bytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const json = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
console.log(JSON.parse(json).message); // 你好

성공적인 Base64 디코드는 유효한 JSON을 보장하지 않습니다. UTF-8 디코드를 처리하고 JSON.parse 별도의 실패 지점으로 표시됩니다. 디코딩된 콘텐츠가 이미 JSON을 포함하는 문자열인 경우 이를 다시 직렬화하면 따옴표와 이스케이프가 추가됩니다. 페이로드가 변경됩니다.

선택한 파일을 바이트로 읽습니다.

브라우저의 경우 File, 사용 arrayBuffer() 기본 바이트가 필요할 때. 사용하지 마십시오 file.text() 이미지, 아카이브 또는 암호화된 파일의 경우 잘못된 문자 시퀀스가 대체 문자가 될 수 있습니다. 대상에 데이터 URI이 필요한 경우, FileReader.readAsDataURL() 래퍼와 Base64 데이터를 제공합니다.

// file is a File selected by the user.
const bytes = new Uint8Array(await file.arrayBuffer());
console.log(bytes.byteLength); // original file size in bytes
// Pass bytes to a byte-oriented encoder, not TextEncoder.

실제 실수를 잡아내는 왕복 검사

디코딩된 바이트를 원래 바이트 배열과 비교합니다. 스크린샷이나 파일 이름을 비교하면 변경된 바이트를 감지할 수 없습니다. 빈 입력, 0~255의 모든 바이트 값, 중국어 텍스트, 이모티콘 및 길이가 최종 그룹에 1~2바이트를 남기는 페이로드를 포함합니다. 파일 배치의 경우 하나의 오류가 다른 성공적인 출력을 덮어쓰지 않도록 각 파일의 이름, 크기 및 결과를 독립적으로 보존합니다.

워크플로에서 의도적으로 API을 호출하지 않는 한 변환을 로컬로 유지하세요. 인코딩된 출력이 포함된 네트워크 요청은 여전히 ​​기본 데이터를 되돌릴 수 있는 형식으로 보냅니다. 브라우저 기능의 바이트 문자열 동작 및 유니코드 제한 사항은 다음을 참조하세요. MDN: btoa().