일단 상황은 이렇다
윈도우로 받으면 멀쩡한 파일명이
맥북 사파리를 사용해서 받으면 외계어 나옴
맥북 크롬에서도 동일하게 '내가해냄.png' 한글 잘 나왔는데!!
그래서 이건 나의 하루를 바친 맥북 사파리에서 제대로 된 한글명 파일 다운로드 받기 가이드다
[1] 능력자가 만들어 놓은 프로그램 사용하기
대단한 사람이 만들어 놓은 프로그램이 있음!
마음 같아선 고객사에 이 파일 주고 사용하라고 하고 싶었다
[2] 인코딩/디코딩 사이트 이용하기
DenCode | Encoding & Decoding Online Tools
Encoding and Decoding site. e.g. HTML Escape / URL Encoding / Base64 / MD5 / SHA-1 / CRC32 / and many other String, Number, DateTime, Color, Hash formats!
dencode.com
역시 대단한 사람이 만들어 놓은 사이트 있음!
여러 사이트가 많지만 인코딩/디코딩이 모두 가능하고 다양한 언어 활용이 가능한 곳은 여기인 것 같음
[3] 서버단에서 처리하기
대망의 진짜 처리 방법
해 놓고 나니까 별거 아닌데 중간에 이상한 함정에 빠져서 4시간을 날렸다
(소스코드만 알고 싶은 분들은 필요소스1, 2만 보시라)
할 일 첫 번째. 맥북 사파리의 userAgent 값 구분하기
일단 윈도우, 맥북 크롬, 아이패드, 아이폰 등에서는 문제 없으니 '맥북에서 접속한 사파리'를 구분해 줘야 했음
이걸 확인하다가 알게 된 건데 윈도우 크롬에서도 userAgent 값을 보면 AppleWebKit, Safari가 모두 나오더라...
알고 보니 이게 인터넷 익스플로러가 누구를 따라 하고 괴롭히면서(?) 더럽혀진 거라고 하던데
엄청 재미있게 설명해 놓은 블로그가 있었는데 다시 찾으려니까 안 보인다
나름 최신 버전의 맥북 사파리 userAgent 값
Mozilla/5.0 (Macintosh; Intel Mac OS X 13_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.5 Safari/605.1.15
필요소스1. 맥북 사파리 true/false 반환 메소드 생성
userAgent에 mac, safari가 들어가면서 chrome, win, mobile은 없는 것으로 조건을 잡았음
/**
* 사파리 여부
* @param userAgent
* @return
*/
public static boolean isSafari(String userAgent) {
if (userAgent != null && userAgent.toLowerCase().indexOf("mac") > -1 && userAgent.toLowerCase().indexOf("safari") > -1
&& userAgent.toLowerCase().indexOf("chrome") == -1 && userAgent.toLowerCase().indexOf("win") == -1 && userAgent.toLowerCase().indexOf("mobile") == -1) {
return true;
} else {
return false;
}
}
https://kakao-tam.tistory.com/110
브라우저 환경별 user-agent 예시
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent User-Agent: / (platform; os version; ) Browser version ; * 소문자로 치환된 값 - macbook, chrome mozilla/5.0 (macintosh; intel mac os x 10_15_7) applewebkit/537.36 (khtml, like gec
kakao-tam.tistory.com
https://www.whatismybrowser.com/guides/the-latest-user-agent/safari
What are the latest user agents for Safari?
The latest user agents for Safari, including the various platforms it runs on. This can be helpful when you need to change your user agent.
www.whatismybrowser.com
https://wormwlrm.github.io/2021/10/11/Why-User-Agent-string-is-so-complex.html
브라우저의 사용자 에이전트는 왜 이렇게 복잡하게 생겼을까? - 재그지그의 개발 블로그
브라우저의 사용자 에이전트(User Agent)에 얽힌 역사적인 이야기를 이해하기 쉽게 정리해봅니다.
wormwlrm.github.io
할 일 두 번째. 맥북 사파리일 경우 인코딩 값 변경
맥북 사파리의 경우 인코딩 기준이 빡빡해서(라고 말하고 한글을 무시한다고 읽는다)
암튼 UTF-8이라는 인코딩 값을 본문 헤더에 명시하지 않으면 자기 마음대로 인코딩을 해 버린다고 한다
헤더에는 밈타입이라든지 여러 설정이 있지만 일단 내가 적용한 Content-Disposition 관련해서만 적은 것이 나와 있다 (아래에)
할 일 세 번째. 삽질
쎄가 빠지게 이것저것 바꿔도 안 먹힌다
4시간 동안 한 거라곤 외계어에서 퍼센트 글자로 바뀐 것뿐
그마저도 세세하게 여기저기 건드리는 동안 외계어 나왔다가 퍼센트 글자 나왔다가... 반복이었음
나는 분명 UTF-8로 변환을 해 주고, 조건도 잘 걸었는데 왜 이래
울면서 챗지피티한테 물어봤다
Q. "도대체 어떤 값을 넘겨 줘야 사파리에서 한글을 표출시켜 주냐"고
A. 자바단에서 '인코딩된 UTF-8 값'으로 넘겨 주면 사파리에서 UTF-8 한글로 변환해 준다고 한다
단, 이러한 예외 상황도 있다고 하지만 나는......
내가 Content-Disposition를 넣은 이후에 다른 조건문에 또 걸려서 Content-Disposition를 덮어씌우고 있는 걸 무려 4시간 후에 발견했음
그냥 제대로 UTF-8 같은 인코딩 값을 넣어 주기만 하면 제대로 나올 것 같다 (시무룩)
UTF-8로 인코딩된 값?
그렇다면 UTF-8로 인코딩된 값은 어떻게 생겼는지가 궁금해짐
정말 아는 거 없었다 싶지만 아무리 이것저것 구글링 해서 긁어 봐도 변하는 게 없으니 매우 답답했다
그래서 챗 지피티한테 또 물어봄 *^^*
UTF-8 인코딩 값 ▶ 얘 같은 형식으로 넘겨 줘야 함 (퍼센트 글자)
%EC%86%8C%EB%AA%85%EC%97%AC%EC%9E%90%EA%B3%A0+%EA%B9%80%EC%8B%9C%EC%97%B0.pdf
Base64 인코딩 값
JUVDJTg2JThDJUVCJUFBJTg1JUVDJTk3JUFDJUVDJTlFJTkwJUVBJUIzJUEwKyVFQSVCOSU4MCVFQyU4QiU5QyVFQyU5NyVCMC5wZGY=
필요소스2. 맥북 사파리 인코딩 UTF-8 헤더 생성
String dnFileName = "내가 해냄.png"; // 실제 한글 파일명
String convFileName = null; // 한글 파일명을 UTF-8로 인코딩할 값
String userAgent = request.getHeader("user-agent"); // js단에서 가지고 온 userAgent값
convFileName = new String(dnFileName.getBytes("utf-8"), "latin1");
convFileName = convFileName.replaceAll("\r?\n", "");
if (isSafari(userAgent)) {
convFileName = java.net.URLEncoder.encode(dnFileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment; filename*=utf-8''" + convFileName + ";");
}
https://soozl91.tistory.com/54
[Spring] 컨트롤에서 파일 다운로드
스프링 컨트롤러에서 파일 다운로드 시키기 다른 예제들을 보면 User-Agent 헤더에 따라 인코딩을 변경해주던데.. 혹시나해서 아래 코드로 통일 시켰더니 5개의 브라우저 모두 한글 파일명으로 제
soozl91.tistory.com
https://gamechangers.tistory.com/98
사파리에서 한글 첨부파일명이 깨질 경우
프로잭트를 진행하다... 사파리에서(정확히는 iOS 웹 뷰에서 다운로드 받았을때) 한글 파일명이 인코딩 되어 다운되는 문제가 발생하였다. 예를들어, 한글 파일.xlsx 명칭의 파일을 다운로드 받았
gamechangers.tistory.com
https://dololak.tistory.com/19
[Java] URLEncoder URLDecoder 클래스
자바 URLEncoding 웹 개발을 하다보면 URL 관련하여 인코딩이 필요한 경우가 있습니다. URL에는 여러가지 규칙이 있고 그 규칙에 사용되는 문자들이 정해져있기 때문에 특정한 값들은 규칙에 맞게 변
dololak.tistory.com
https://m.blog.naver.com/writer0713/220921933255
[java] String과 getBytes 메소드
오픈소스를 보다가 다음과 같은 메소드를 사용한 걸 발견했다. 위 메소드를 보고 가장 처음 든 궁금증은 &#...
blog.naver.com
replaceAll("\\+", "%20"); 의 필요성
처음 한글이 떴을 때 웃음을 감추지 못하고 + 없애 본다고 또 열심히 구글링 했다
UTF-8의 언어로 %20 == + 이기 때문에 치환해 준 뒤, 드디어 맥북 사파리에서 다운로드 했을 때 완전한 한글명의 파일을 얻었다!
(스택오버플로우랑 온갖 외국인 사이트까지 다 뒤지면서 외국인화 된 내 말투로 열심히 한 거 인증)