폼 전송된 한글 문자열이 깨질 때

UTF-8 문자셋을 사용하는 HTML 페이지에서 EUC-KR 문자셋을 사용하는 HTML 페이지로 폼 데이터 전송을 하면, 원래 의도했던 글자가 아닌 해괴한 문자가 나타납니다.

해괴한 문자
해괴한 문자

물론, EUC-KR 페이지에서 UTF-8 페이지로 보낼 때도 마찬가지 현상이 나타납니다(출현하는 외계어는 다르겠군요).

하지만, 해결할 방법은 있습니다. HTML 스펙에는 이런 상황을 위해 <form> 태그에 accept-charset 이라는 속성을 준비해두었습니다. 정확한 용도는 “입력받은 데이터를 서버에서 다루거나 처리할 수 있는 문자셋”을 지정하는 것에 있습니다. 다시 말해, 서버에서 허용하는 문자셋을 지정함으로써, 브라우저가 현재의 데이터를 해당 문자셋으로 변환해서 보내도록 하는 것입니다.

이쯤에서 “이제 됐다”라고 생각하실 분이 계시겠지만, 안타깝게도 우리의 연로하신 Internet Exploreraccept-charset 을 제대로 인식하지 못합니다. 정확하게는 속성으로도 사용할 수 있고, 자바스크립트로도 읽거나 쓸 수 있지만 지원하는 문자셋이 아주 한정적입니다. sitepoint 에서는 이 속성에 대한 IE의 지원을 Buggy(버그가 많은)라고 태깅해두었습니다. 한정적인 문자셋에 우리가 많이 사용하는 euc-kr이나 utf-8은 포함되지 않으므로, 결국 다른 방법을 찾아야 합니다.

일단 IE를 제외한 Firefox, Google Chrome, Safari, Opera 등의 브라우저는 이 속성을 잘 지원하므로 이들 브라우저를 위해 form 에 다음과 같이 속성을 표시합니다.

<form ... accept-charset="서버로 보낼 인코딩">

서버로 보낼 인코딩 부분은 현재 문서의 문자셋과 상관없이 데이터를 서버측에 어떤 문자셋으로 보낼 것인지를 지정합니다. 예를 들어, UTF-8 페이지에서 EUC-KR 페이지로 폼 전송을 한다고 하면 euc-kr 혹은 EUC-KR 이라고 입력하면 됩니다.

이제 IE를 위한 처리를 해주는 자바스크립트를 작성합니다.

// by gony(http://mygony.com) - 20081216
function emulAcceptCharset(form) {
    if (form.canHaveHTML) { // detect IE
        document.charset = form.acceptCharset;
    }
    return true;
}

이제 이 함수를 onsubmit 이벤트에 할당합니다. 이 시점에서는 return true; 가 필요하지 않지만 포함되어 있는데, 그 이유가 곧 나타납니다. 🙂

<form ... accept-charset="서버로 보낼 인코딩"  onsubmit="emulAcceptCharset(this)">

보통은 여기서 끝이지만, 폼 검사기(form validator)를 사용하시는 분들 중에는 어느 시점에 이 함수를 포함시켜야 할지 혼란스러울 수 있습니다. 이 함수는 항상 submit 핸들러의 가장 마지막에 포함되어야 합니다. 따라서, 만약 여러분이 사용하는 폼 검사기의 함수 이름이 validate 라고 한다면, 다음과 같은 형태로 사용하시면 됩니다.

<form ... accept-charset="서버로 보낼 인코딩"
  onsubmit="return validate(this) && emulAccpetCharest(this)">

validate(this) 부분은 사용하시는 폼 검사기에 따라 달라져야 함을 주의하시기 바랍니다.

이 스크립트는 Firefox 1+, Safari 1.3+, Chrome 1+, Opera 9.2+, IE 5.5+ 에서 사용가능합니다.

댓글을 남겨주세요