곧 다가올 IE 업데이트 덕분에 스마트 클라이언트를 사용하는 P 건설을 지원해야 했습니다. HTML 내에 직접 사용된 스마트 클라이언트를 위한 OBJECT 태그를 외부 .js 파일로 옮기다가 황당한 시츄에이션에 직면해서 몇 자 적어 봅니다.
사건 개요
2월 중순으로 계획되었다던 IE 업데이트는 3월 1일로 연기되었다는 이야기가 있다. 이 연기가 국내에만 한한 것인지, 전 세계에 대한 것인지는 확실하지 않다. 어찌 되었건 3월 1일(?) 업데이트는 자동 업데이트가 아닌 Windows Update 사이트(http://windowsupdate.microsoft.com)에 접속하여 "권장"으로 설정된 업데이트를 다운로드 받을 수 있음을 말한다(적어도 필자는 그렇게 알고 있다). 4월 중순으로 계획되어 있는 업데이트는 IE 보안 패치의 일부로서 Windows Update 서비스를 통해 자동으로 다운로드 된다. 따라서 적어도 4월 중순까지는 사이트를 변경하고 테스트를 해야 한다는 말이다.
IE 업데이트에 대한 진실 혹은 거짓말 포스트에서 밝혔듯이 이번 변경은 스마트 클라이언트에도 영향을 준다. 그래서 필자가 컨설팅 한 P 건설사에 기존 코드를 변경할 가이드를 작성해야만 했다. 프로젝트 투입은 끝났지만, 고객 서비스 차원에서 작업을 해야만 했기에...
ActiveX 컨트롤 활성화 관련 기술 문서의 지침 대로 OBJECT 태그를 외부 .js 에서 활성화하도록 하면 되는데, P 건설사는 PARAM 태그를 ASP.NET 에서 동적으로 랜더링 하기 때문에 약간의 트릭을 사용해야 했지만 어렵지 않게 구현이 가능했다.
그런데... 요상하게도 외부 스크립트를 참조하기 위해 다음 코드를 집어 넣으면서 예전에 잘 작동하던 스크립트들이 죄다 제대로 작동하지 않는 것이 아닌가?
<script src="activate.js" />
위 코드만을 빼면 또 예전처럼 잘 작동하는 것이 아닌가? C8, C8, C8, ....
원인
무엇이 문제일까? 1시간을 넘도록 졸라 뺑이 친 후에 겨우 알아낸 원인은 SCRIPT 버그로 추측되는 이상한 행동이었다. 즉, SCRIPT 태그는 XML 처럼 self closing tag를 사용하면 스크립트 태그의 끝을 인식하지 못한다는 것이다. 쉽게 말하자면 /> 을 사용하여 SCRIPT 태그를 닫으면 다음에 </script> 태그를 만날 때까지의 내용을 브라우저가 전혀 스크립트로 인식하지 않는다는 것이다. 위 코드를 다음과 같이 수정하면 매우 잘 작동한다.
<script src="activate.js"></script>
XHTML 이 대세로 굳어가는 판에 XHTML 스타일의 <script ... /> 가 제대로 처리되지 않는다는 것에 놀라지 않을 수 없었다. KB를 뒤져보았지만 이에 관련된 내용은 찾을 수 없었다. 그래서 구글 신에 물어보니 이러한 현상을 겪은 여러 사람을 찾을 수 있었다. IE의 버그로 밖에 보이지 않는 SCRIPT 태그의 이상한 행동 덕에 필자는 졸라 삽질을 해 댄 것이다. 독자들은 절대로 script 태그에 대해서는 self closing tag를 사용하지 않을 것을 바란다.
덤으로 알아낸 것
검색을 하면서 덤으로 알아낸 것이 있어서 알려주자면, 스크립트 코드 내에 </script> 문자열이 포함되면 브라우저는 그것을 스크립트의 끝으로 간주해 버린다는 것이다. 예를 들어 다음과 같은 스크립트는 정상적으로 작동하지 않으며, "종결되지 않은 문자열 상수입니다" 라는 오류 메시지를 뿌린다.
<html>
<head>
<script language="javascript">
function testFunc()
{
alert("<script> and </script> test");
}
</script>
</head>
<body>
<input type="button" value="Test !" onclick="testFunc()">
</body>
</html>
이유는 스크립트의 문자열 내에 사용된 </script> 문자열이 실제 스크립트의 종료 태그로 인식되어 버리기 때문이다.
이를 해결하기 위해서는 직접적으로 </script> 문자열이 스크립트 코드 내에서 사용되지 않도록 하면 된다. 자바 스크립트의 경우 백슬래시 문자(\)를 사용하여 <\/script> 라는 문자열을 사용하면 된다. 자바 스크립트는 백슬래시 문자를 무시하기 때문에 정상적으로 문자열이 처리된다. ASP 코드에서 많이 사용되는 VB 스크립트의 경우에는 chr(60) & "/script>" 와 같은 코드를 사용하여 직접적으로 </script> 라는 문자열이 사용되지 않도록만 하면 된다. 위 코드를 정상 작동하도록 수정하면 다음과 같다.
<html>
<head>
<script language="javascript">
function testFunc()
{
alert("<script> and <\/script> test"); // use back slash
}
</script>
</head>
<body>
<input type="button" value="Test !" onclick="testFunc()">
</body>
</html>
이러한 </script> 문자열에 대한 내용은 KB의 다음 자료에 명시되어 있으며, 버그가 아닌 by design 이란다.
왜 이딴 행동이 by design 인지 이해가 안 가지만 알아두면 정신건강에 유익할 것 같아서 몇 마디 써 봤다...