-
TIL - Mac 업로드 파일 한글 깨짐 (자모분리현상)개발 2022. 4. 19. 23:23
트러블 슈팅
Mac 환경에서 업로드한 파일의 이름이 Window 환경에서 자모분리되어 다운받아지는 이슈를 해결
원인
유니코드란?
유니코드는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 산업 표준이다. 유니코드는 유니코드 협회가 제정한다. 또한 이 표준에는 ISO 10646 문자 집합, 문자 인코딩, 문자 정보 데이터베이스, 문자들을 다루기 위한 알고리즘 등을 포함하고 있다. - 위키백과
유니코드와 관련된 개념으로 유니코드 등가성 이라하는 것이 있는데, 이 것은 유니코드 문자 인코딩 표준 사양이라 말하며, 표준 문자와 문자 집합과의 호환성을 허용하기 위해 표준으로 도입되었다.
유니코드 등가성이라는 표준은 유니코드 정규화 절차를 정의한다.
유니코드 정규화(Unicode normalization)는 모양이 같은 여러 문자들이 있을 경우 이를 기준에 따라 하나로 통합해 주는 일을 가리킨다. 그 기준으로는 아래 표와 같이 NFD, NFC, NFKD, NFKC가 있다.
https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C_%EB%93%B1%EA%B0%80%EC%84%B1
분석
Mac과 Window에서 사용하는 유니코드 정규화 방식의 차이
Window - NFC 정규화 방식
NFC 정규화 방식은 정준 분해한 뒤에 다시 정준 결합 하는 방식으로 설명되어 있다.
이 말을 쉽게 설명하면 모든 음절을 분해하고 다시 결합하여 저장하는 방식을 말한다.
예를 들어 한을 입력 했다고 가정해보자, NFC는 모든 음절을 분해하여 재결합 하기 때문에 저장된 문자로
한이라는 문자로 저장된다.
Mac - NFD 정규화 방식
NFD 정준분해 정규화 방식을 사용하고 있다.
이 말은 모든 음절을 분해하여 자모코드를 이용하여 저장하는 방식을 말한다.
예를 들어 한을 입력 했다고 가정해보자, NFD 방식은 모든 음절을 분해하여 따로 저장하게 된다.
Mac 에서 업로드한 파일이 Window 환경에서 다운로드 되었을 경우
개발중인 웹 페이지에 사용자가 서비스 소개서를 다운받는다.
나의 개발환경은 Mac에서 진행되어 저장된 파일이 NFD 방식으로 업로드되어 있는데,
윈도우를 환경의 사용자가 파일을 다운받게 될 경우 NFD 방식으로 저장된 문자열을 NFC 방식으로 읽어드리게 되어
자모분리 현상이 생겨났다.
정규화 방식을 바꿀수 없을까?
안되는건 없다, 다만 내가 찾지 못했을 뿐이지.. 찾아보자.
역시나 많은 개발자들이 비슷한 이슈를 경험했고, 자바스크립트 내장 API에서도 유니코드 정규화 방식을 지정 할 수 있는 메서드가 존재한다.
MDN -> String.prototype.normalize()
String.prototype.normalize() - JavaScript | MDN
normalize() 메서드는 주어진 문자열을 유니코드 정규화 방식(Unicode Normalization Form)에 따라 정규화된 형태로 반환합니다. 만약 주어진 값이 문자열이 아닐 경우에는 우선 문자열로 변환 후 정규화
developer.mozilla.org
사용방법은 간단하게 매개변수로 지정하고자 하는 정규화 방식을 String으로 입력하면 해당 값의 정규화 방식을 바꿔준다.
str.normalize([form])
유니코드 정규화 방식에서 사용하는 4가지 방식을 모두 지원하며, 매개변수가 생략된 경우 기본값으로 "NFC" 방식을 사용한다.
문제해결
a 태그의 download 속성을 통해 사용자가 다운받는 파일명을 입력해 제공하고 있었다.
이때 Mac 환경에서 NFD 방식으로 정규화된 문자이기에 nfcNormalization 이라는 유틸 함수를 작성하여
정규화 방식을 바꿔 문자를 제공해 이슈를 해결했다.
이렇게 해결된 파일명은 Mac, Window 환경에 상관없이 문자열이 NFC 방식으로 저장되있기 때문에 자모분리가 일어나지 않고 정상적인 파일명을 제공 할 수 있었다.
'개발' 카테고리의 다른 글
TIL - React Table Library #1 (2) 2022.05.02 TIL - Next.js Google Analytics 코드 적용하기 (1) 2022.04.26 JS - Map (0) 2022.04.13 React - react hook form (0) 2022.03.31 TIL - CSS Module (0) 2022.03.28