티스토리 뷰

hacking/web

자바스크립트의 encodeURI와 친구들~

Ho Eyo He Hum! iolo 2008.05.13 16:47
자바스크립트에는 URL 인코딩과 관련해서 4가지 함수가 있다.
encodeURI(), encodeURIComponent(), escape()/unescape() 이 그것인데...
구글신께 여쭈었더니... 이렇게 다르다고 말씀해 주셨다.

정말?
일단, 실험을 해보기로 했다.

저 사이트에 나온 파일을 UTF-8EUC-KR로 각각 저장했다.

test-utf8.html, test-euckr.html
<html>
<body>
<script type="text/javascript">
var s;
s = encodeURI('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
s = encodeURIComponent('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
s = escape('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
</script>
</body>
</html>

그리고 각각의 파일의 헤더 영역에 다음의 메타 태그들을 끼워넣은 파일을 두개 더 만들었다.

test-utf8-meta.html
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />

test-euckr-meta.html
<meta http-equiv="Content-Type" content="text/html;charset=EUC-KR" />

그리고, 이 페이지들을 한글 IE7, 영문 IE6, 영문 IE7, FF 2.0 으로 브라우져로 테스트 했다. 혹시나 싶어서 IE의 경우엔 항상 "UTF-8로 URL을 보내기" 옵션도 바꿔가면서 해봤는데... 말그대로 URL을 보내는 것이 아니라서 차이가 없었다.

이런 삽질을 왜 하냐 싶겠지만...
내가 기대한 것은 첫번째 경우지만... 결과를 보면... 정말... 다들 제각각이다. -.-;;;;

test-utf8-meta.html, test_euckr.html, test-euckr-meta.html, 한글 IE7, FF
test-utf8-meta.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%EC%86%8C%20%EC%84%A4.html
http%3A%2F%2Fwww.google.co.kr%2F%EC%86%8C%20%EC%84%A4.html
http%3A//www.google.co.kr/%uC18C%20%uC124.html

test-utf8.html, 한글 IE7
http://www.google.co.kr/????html
http%3A%2F%2Fwww.google.co.kr%2F%3F%3F%3F%3Fhtml
http%3A//www.google.co.kr/%3F%3F%3F%3Fhtml

test-utf8.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%C3%AC%E2%80%A0%C5%92%20%C3%AC%E2%80%9E%C2%A4.html
http%3A%2F%2Fwww.google.co.kr%2F%C3%AC%E2%80%A0%C5%92%20%C3%AC%E2%80%9E%C2%A4.html
http%3A//www.google.co.kr/%EC%u2020%u0152%20%EC%u201E%A4.html

test-euckr.html, 영문 IE6/7(한글 언어 팩 없음)
test-euckr-meta.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%C2%BC%C3%92%20%C2%BC%C2%B3.html
http%3A%2F%2Fwww.google.co.kr%2F%C2%BC%C3%92%20%C2%BC%C2%B3.html
http%3A//www.google.co.kr/%BC%D2%20%BC%B3.html

정리해보자:
  1. meta 태그는 반드시 넣어줘야 한다. 없으면... IE가 힘들어 한다.
  2. meta 태그가 있어도 영문 환경에서 한글 언어 팩이 안깔려있으면 euc-kr은 황~이다.
  3. URL을 통째로 인코딩할 때는 encodeURI(), URL의 파라메터만 인코딩할 때는 encodeURIComponent()를 쓰면 된다.
  4. escape()/unescape()는 잊어버려라.
  5. 왠만하면 URL에 인코딩이 필요한 꺼리(한글... 공백... 이런 거)는 넣지 말자.

덧1.
여기서 의문점 한가지 더! 그렇다면 자바의 java.net.URLEncoder는 어떨까?
결론은 이녀석은 자바스크립트의 encodeURI()와 동일하다.
주의할 점은 java.net.URLEncoder의 두개의 함수 중의 파라메터가 두개인 녀석(캐릭터 인코딩을 지정해주는)을, 두번째 파라메터를 "UTF-8"로 지정해서 사용해야 한다는 것이다. 파라메터가 한 개인 첫번째 녀석을 쓰면... 플랫폼의 기본 인코딩(-Dfile.encoding)을 따라가므로 개차반(?) 난다.
자바에선 이것 저것 다 잊어버리고... 그냥 바이트 배열로 뽑아서 commons-codec의 URLCodec을 쓰는게 정신 건강에 이롭다.

덧2.
나름 좀 한다는 개발자들 조차 인코딩과 캐릭터셋에 대해서 오락가락한다. 자바 API 개발자들 조차 헷갈리고 있으니...(java 1.6의 String#getBytes()와 1.3의 String#getBytes()의 파라메터 이름을 보시라~~. commons-codec의 URLCodecgetEncoding()getDefaultCharset()도 보시라~~). 오죽하랴마는... 인코딩은 인코딩이고, 캐릭터셋은 캐릭터셋이다. 말하자면, "유니코드(캐릭터셋)에 속한 글자들은 UTF-8(인코딩)이나 UTF-16(인코딩)등으로 표현할 수 있다." 정도 일까? 그러니까, UTF-8이건 EUC-KR이건, URL 인코딩을 하는 입장에선 그냥 바이트 배열일 뿐이다. 더 어렵나?? =3=3=333

댓글
댓글쓰기 폼