Tistory View
음... 이 글을 끝까지 읽는 것을 추천한다.
UTF-8로 처리되지않는 btoa 함수
javascript에서 base64 인코딩을 하려고 하던 중 좀 어의가 없는 상황을 만났다. 어찌보면 틀렸다고도 할 수 있고, 맞다고도 할 수 있지만...
문제의 발생은 한글은 처리가 안된다는 것이다. 한글을 입력할 경우 다음과 같은 오류[에러]를 console log창에 서 확인 할 수 있다.
let a = 'abcd';
let b = '갓댕치';
console.log( btoa( a ) ); // [YWJjZA==] // 정상
console.log( btoa( b ) ); // < ERROR
// 불여우 : Uncaught DOMException: String contains an invalid character
// 중금속 : Uncaught DOMException: Failed to execute 'btoa' on 'Window'
// The string to be encoded contains characters outside of the Latin1 range.
한글을 넣으면 위와 같이 문제가 발생한다. 한글 뿐만아니라 ASCII의 기본 문자를 제외하고는 전부 터지는 오류다. 이 곳에는 당연히 이모티콘도 문제에 포함된다.
Base64를 왜 쓰는지 모르는 이가 카피하는 코드
구글을 뒤져보면 다음과 같은 코드가 있다.
// base64 인코딩
s = btoa(encodeURIComponent(str));
// base64 디코딩
s = decodeURIComponent(escape(atob( str )));
이 코드를 javascript에서만 사용한다면 문제가 없지만, base64를 쓰는 이유가 text로만 표현이 가능한 문서에 binary데이터를 넣거나, text로만 전송해야하는 곳에 사용하려고 나온 것인데, 인코딩 결과가 UTF-8이 아니라 x-www-form-urlencoded로 나오기 때문에 받는 쪽이나 문서에 삽입하려는 경우, decodeURIComponent같은 작업을 추가로 해줘야 한다.
base64를 쓰는 또다른 이유가 생성된 데이터가 원본에 33%만 커진다는 장점을 이용하는 것인 데, 이 것은 크기가 대따 커진다. base64를 쓰려는 의도와 전혀 맞지 않는 것이다.
현실적으로 쓰기 좋은 코드
그래서 MDN에서 제시하는 방법은 다음과 같다.(좀더 정확히 Johan Sundström 님하가 올린 것을 MDN에 기재됨)
let str = '갓댕치';
str = btoa(unescape(encodeURIComponent( str )));
console.log( 'result =[' + str + ']'); // result =[6rCT64yV7LmY]
이 방법도 문제가 있다.. 이 건 뭐 어떻하라는 건지..
문제는 unescape함수가 워낙 예전..javascript가 나올때 거의 최초에 나온 함수라서 이게 "deprecated될까? 말까?"한 상황이다. 하지만 이게 UTF-8을 쓰기에는 가장 잘 만들어진 코드라서 Johan Sundstro[움라우트]m님하의 코드를 올리겠다.
function utf8_to_b64( str ) {
return window.btoa(unescape(encodeURIComponent( str )));
}
function b64_to_utf8( str ) {
return decodeURIComponent(escape(window.atob( str )));
}
이 코드는 escape, unescape함수가 사라지지 않는 그 날까지 사용가능기에, 사라질 때쯤 다른 코드를 사용하기를 바란다.
일단은 이 코드를 퍼다 쓰는 것을 필자는 권장한다.
추가로 알아두면 좋은 것이 js의 string타입은 UTF-16을 쓰고 있다.
레퍼런쑤
다음은 이 글을 작성하기위한 레퍼런스들 인데, 원래 필자는 위의 코드들이 맘에 안들어 새로 짜서 올리려고 했지만, Johan님하의 코드가 현실적으로 가장 깔끔하기 때문에 그냥 쓰기로 했다.
UTF-8용으로 가장 정확한 코드의 설명과 링크, 이 링크의 하단에 escape를 쓰지않고 일일이 작성한 코드가 있다. 그 코드를 escape함수가 사라지는 그날 적용을 해야한다.
https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder
https://developer.mozilla.org/en-US/docs/Web/API/TextDecoder
이 링크는 utf-8과 javascript의 string을 서로 변환하는 오브젝트에 대한 링크다.
아직 실험실 버전이지만, 브라우저들이 잘 지원하니 문제 없이 쓸 수 있다.
'web > javascript' 카테고리의 다른 글
HTML Image lazy loading[느린 로딩] #3 (3) | 2020.12.16 |
---|---|
HTML Image lazy loading[느린 로딩] #2 (0) | 2020.12.14 |
HTML Image lazy loading[느린 로딩] #1 (0) | 2020.12.12 |
Javascript 변수내용(String, base64, blob, data url) 다운로드 (0) | 2020.02.23 |
예제 Zip파일 만들기: Javascript로 Zip파일 다루기 (2) | 2020.02.23 |
- Total
- Today
- Yesterday
- 에어콘
- 적금
- 재태크
- 경제보복
- 블로그
- 예금
- OpenGLes
- OpenGL ES
- 재테크
- 컴퓨트셰이더
- 사용료
- 컴퓨트쉐이더
- 아끼는 법
- 에어컨
- choreographer
- gpgpu
- 안드로이드
- 전기료
- texture
- 공유 컨텍스트
- 금리
- Android
- 텍스처
- 전기요금
- 애드센스
- ComputeShader
- 전기세
- 티스토리
- 애드핏
- TTS
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |