본문 바로가기

웹사이트

AJAX Status 헤더를 이용한 에러 처리시 한글 깨짐

개인적으로 AJAX를 사용할때 서버(PHP)에서 에러를 리턴하기 위해서 헤더의 Status를 이용하고 있습니다. 예를 들어, PHP에서 에러를 리턴할때 다음과 같이 했습니다.


 header('Status: '.$errorMessage, true, 400);

 
그리고 Javascript에서는 해당 에러를 캐치하기 위해서 JQuery를 이용할 경우 다음과 같이 했습니다.

$.post(url, requestData, function(returnData) {
    // Do something
}, 'json').error(function(jqXHR) { 
    var errorMessage = jqXHR.getResponseHeader('Status');
    if ((errorMessage != null) && (errorMessage != 'null')) {
        alert(jqXHR.getResponseHeader('Status'));
    }
});


하지만 이렇게 할 경우 Chrome, 파이어폭스를 비롯하여 IE 일부 버전에서는 한글이 깨지는 현상이 발생합니다.

이를 해결하기 위해서 서버 사이드에서 에러를 리턴할 때와 클라이언트 사이드에서 에러를 받을 때 동일한 알고리즘으로 문자를 변화시키는 방법을 사용할 수 있습니다.

즉, 서버쪽 스크립트(PHP)에서는 다음과 같이 수정합니다.

 header('Status: '.rawurlencode($errorMessage), true, 400);


그리고, 클라이언트쪽 스크립트(Javascript)에서는 다음과 같이 수정합니다.

$.post(url, requestData, function(returnData) {
    // Do something
}, 'json').error(function(jqXHR) { 
    var errorMessage = jqXHR.getResponseHeader('Status');
    if ((errorMessage != null) && (errorMessage != 'null')) {
        alert(decodeURIComponent(jqXHR.getResponseHeader('Status')));
    }
});

이렇게 하면 서버에서 Header를 통해서 전달한 에러메세지를 한글 꺠짐 없이 정상적으로 출력할 수 있습니다. (위의 소스에서 null 체크는 불필요한 null 에러 표기를 막기 위한 것으로 제외하실 수 있습니다)



덧붙여서, 만약 서버 환경이 EUC-KR을 사용하고 있다면 서버에서 에러를 보낼 때 UTF-8로 일단 변환을 해야합니다.

 header('Status: '.rawurlencode(iconv('CP949', 'UTF-8', $errorMessage)), true, 400);


또한 EUC-KR을 사용하는 경우 클라이언트(Javascript)에서 서버(PHP)로 데이터를 보내야 할때도 encodeURIComponent 함수를 이용하고 서버에서 받을 데이터는 다시 변환시키는 방법으로 한글의 깨짐을 방지할 수 있습니다. (단, JQuery를 사용하실 경우 클라이언트에서 서버로 보낼 경우 자동으로 encodeURIComponent로 변환되므로 따로 작업할 필요가 없고, PHP에서만 처리를 해주면 됩니다)

PHP에서 UTF-8로 받은 데이터는 다음과 같이 변환할 수 있습니다.

$value = iconv('UTF-8', 'CP949//TRANSLIT', $value);
 
여기서 CP949//TRANSLIT 뒤에 붙은 //TRANSLIT 옵션은 존재하지 않는 문자에 대해서 유사문자로 대체하는 옵션입니다. 사용하지 않을 경우 변환 불가능한 문자부터 손실이 되므로 사용하는 것을 권장합니다.