브라우저가 XHTML을 해석하는 방식

일반적인 환경에서는 XHTML 규격에 맞게 적성된 모든 문서가 실질적으로 HTML과 동일하게 처리됩니다. 이번 글에서는 왜 그런 결과가 생기는지 그 이유를 알아보겠습니다.

이 글은 앞선 글과 마찬가지로 Tommy Olsson이 Site Point 포럼에 쓴 글을 번역한 것으로 부분적으로 dagger 마크(†)로 시작하는 보충 설명을 넣었습니다. 따라서 이 글의 저작권은 원문의 저작자인 Tommy Olsson과 Site Point에 있으며, 블로그 전체에 적용되는 CCL보다 우선적으로 적용됩니다.

MIME 타입은 어떻게 적용되는가?

웹에 있는 문서나 자원(resource)을 HTTP 프로토콜을 통해서 요청하면 웹 서버는 요청에 맞는 결과(response)를 보내주게 된다. 요청에 대한 답변은 하나 이상의 헤더와 빈 행(CR+LR), 그리고 문서의 내용(body)으로 구성되는데, HTML이나 XHTML 문서에서는 우리가 작성한 마크업이 그 내용이 된다.

HTTP 헤더는 전송할 문서에 대한 메타 정보를 제공하게 되는데, 그 중에서 가장 중요한 헤더가 Content-Type 헤더이다. 이것은 브라우저와 같은 사용자 에이전트(user agent)에게 전송할 문서가 어떤 내용을 담고 있는 문서인지 알려주는 역할을 한다. 또한 이 헤더는 문서가 어떤 문자 인코딩을 사용하는지에 관한 정보도 포함할 수 있다. 일반적인 HTML 헤더는 아래와 같이 표현된다.

Content-Type: text/html; charset=iso-8859-1

여기에서 text/html 부분을 MIME 타입이라고 부르는데 이메일 전송에서 사용되던 문서의 내용을 정의하는 규격으로 HTTP 전송에도 동일하게 적용된다.

예로 든 MIME 타입은 미디어 타입 이름(text)과 서브타입 이름(html)으로 구성되며, 문자 인코딩 정보는 생략이 가능하다.

RFC 2854 규약에 따라서 이 MIME 타입은 문서의 내용이 HTML임을 나타낸다. 그러므로 브라우저는 해당하는 문서가 마이크로소프트의 워드 문서나 GIF 이미지, 또는 XHTML 문서라 해도 무조건 HTML로 인식하고 해석한다. 다시 말해서 MIME 타입이 text/html일 경우에 그 문서는 XHTML이 아닌 HTML 문서가 된다.

XHTMLHTML로 해석된다는 것은 XML에서만 가능한 기능들을 전혀 사용할 수 없고, 반대로 HTML에서만 가능한 기능들은 사용할 수 있다는 의미이다. 하지만 그렇게 HTML의 기능을 사용하는 것은 XHTML로 마크업한 원래의 목적에 위배되는 일이 된다.

그러면 XHTML은 어떤 MIME 타입을 사용해야 하는가?

브라우저가 XHTMLXML 문서로 인식하고 해석하려면 아래의 세 가지 MIME 타입 중의 하나를 사용해야 한다.

  • application/xhtml+xml (추천함)
  • application/xml
  • text/xml (추천하지 않음)

W3C가 추천하는 MIME 타입은 RFC 3236 규약에 정의된 application/xhtml+xml 타입이다. 하지만 인터넷 익스플로러는 2006년 6월 현재까지 이 MIME 타입을 지원하지 않는다.

text/xml 타입도 사용할 수 있지만 기본 문자 인코딩을 처리하는 방식의 문제 때문에 추천하지 않는다. 이 타입에서는 HTTP 헤더에 인코딩 정보가 반드시 포함시켜야 하는데, 이것은 XML 선언에서 변경할 수 없다. 게다가 이 타입의 기본 인코딩은 도움이 되지 않는 US-ASCII 방식이다.

브라우저는 XHTML을 제대로 지원하는가?

아니다. 오페라, 파이어폭스, 사파리 같은 일부 브라우저는 XHTML을 지원하지만, 가장 많은 사용자를 확보하고 있는 인터넷 익스플로러가 XHTML을 제대로 지원하지 않는다.

호환성을 위해서 W3C는 XHTML 1.0 규격에 포함시킨 HTML 호환성 가이드라인에서 text/html MIME 타입을 사용하는 방법을 제시하고 있다. 하지만 이 MIME 타입을 사용하면 모든 브라우저는 해당 문서를 HTML 문서로 인식하고 해석한다.

실질적으로 모든 브라우저가 self-closing 태그(예: <br />)의 슬래시 기호를 무시하는 해석상의 버그를 갖고 있으므로 XHTMLHTML과 동일하게 해석된다.

XML 문법에서는 self-closing 태그의 슬래시 기호 앞에 공백을 넣지 않아도 문법적으로 아무 문제가 없으며, <br /> 태그를 <br></br> 태그처럼 사용할 수도 있습니다. 하지만 XHTML에서는 호환성을 위해서 이런 문법을 허용하지 않습니다.

<meta/> 태그에 지정한 MIME 타입도 적용되는가?

그렇지 않다. 브라우저는 HTTP 요청에 대한 답변으로 전송받는 내용(body)을 해석하기 전에 그 문서가 어떤 문서인지를 알아야 한다. 브라우저가 아래와 같은 메타 태그를 발견했을 때에는 이미 늦은것이다.

<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8"/>

MIME 타입은 반드시 HTTP 헤더로 보내야 한다. 문자 인코딩에 대한 정보는 메타 태그가 아닌 XML 선언에서 명시되어야 한다.

† Lachlan Hunt의 블로그에 실린 Content-Type에 관한 글을 참고해서 내용을 보충하자면 이렇습니다. 메타 태그의 Content-Type은 브라우저 같은 사용자 에이전트(user agent)를 위해 만들어진 것이 아니라 서버가 HTTP 헤더에 실어 보낼 Content-Type을 동적으로 변경하기 위한 목적으로 고안되었지만, 실제로는 그 역할을 못하고 있습니다. 이 메타 태그가 수행하는 유일한 역할은 W3C가 제안한 바와 같이 문서의 인코딩 정보를 알려주는 것입니다.

그러면 HTTP 헤더가 없는 로컬 문서는 브라우저가 어떻게 해석하는가?

오페라와 파이어폭스는 로컬 문서의 확장자를 보고 어떻게 해석해야 할지 판단한다. 예를 들어서 xhtml, .xht, .xml. 확장자를 인식할 수 있다. 인터넷 익스플로러는 XHTML을 전혀 지원하지 않으므로 이런 방법이 적용되지 않는다.

그러면 어떻게 해야 XHTML에 맞는 MIME 타입을 지정할 수 있는가?

서버 환경에 따라서 방법에 차이가 있지만, 아파치 서버의 경우 다음과 같은 AddType 지시문을 사용할 수 있다.

AddType application/xhtml+xml .xhtml .xht

이 지시문은 .xhtml과 .xht 확장자를 갖는 문서를 application/xhtml+xml MIME 타입으로 전송하도록 서버에 지시한다. 이 명령은 아파치 서버의 전역 설정(/etc/httpd.conf)이나 웹 디렉토리의 .htaccess 파일에 적용된다.

이런 설정 파일에 접근할 수 없는 경우에는 서버-사이드 스크립트 언어를 사용해서 같은 결과를 얻을 수 있다. 예를 들어서 PHP 언어를 사용한 다음 코드를 이용할 수 있다.

header('Content-Type: application/xhtml+xml; charset=utf-8'); 

이 헤더가 문서의 내용이 전송되기 전에 브라우저에게 전해져야 한다는 것을 명심하라.

XHTMLapplication/xhtml+xml 타입으로 전송하면 어떤 장점이 있는가?

말 그대로 브라우저가 XHTMLXHTML로 인식한다. XHTML을 사용할 경우에만 얻을 수 있는 장점 때문에 XHTML 문서를 작성했다면 그 장점을 그대로 누릴 수 있다.

Content Negotiation 방식을 사용하면 해결되지 않는가?

Content Negotiation은 하나의 HTTP 요청에 대해서 두 가지 이상의 자원(문서, 이미지 등)을 준비해서 사용자 에이전트(user agent)에 따라 선택적으로 제공하는 방법이다. 예를 들어서 application/xtml+xml을 지원하는 오페라, 파이어폭스, 사파리 브라우저는 XHTML 문서를 application/xtml+xml 형태로 제공하고 인터넷 익스플로러가 요청할 때에는 HTML 마크업으로 작성된 HTML 문서를 text/html 형태로 보낼 수 있다.

하지만 이런 방법으로 얻을 수 있는 이점은 다른 컴퓨터 광(geeks)들에게 자신의 능력을 보여주는 것 외에는 전혀 없다. HTML로 변환시킬 수 있는 문서라면 XML만이 지원하는 기능을 전혀 사용하지 않았을 것이기 때문이다. 그렇다면 이름만 다른 두 개의 문서(XHTML, HTML)를 준비하는 것보다 HTML 4.01 스팩을 따르거나 XHTMLtext/html로 제공하는 것이 훨씬 쉬운 방법이다.

Content Type Negotiation은 더 의미가 없다. 같은 문서를 브라우저에 따라 서로 다른 Content-Type으로 보내서 얻을 수 있는 이점은 전혀 없다.

† Content Negotiation을 쉽게 이해하려면 GIF 이미지와 PNG 이미지를 생각하면 됩니다. 동일한 두 가지 이미지를 준비해서 PNG를 제대로 지원하지 않는 인터넷 익스플로러 6.0에게만 GIF 이미지를 전송하는 방법이지요. 자세한 설명은 Content Negotiation에 관한 위키피디아 문서를 참고하세요.

Content Type Negotiation은 모든 요청에 대해 동일한 내용(content)을 전송하면서 HTTP 헤더 정보만 달리하는 것을 말합니다. 동일한 문서가 XHTML도 되고, HTML도 되는 방식입니다.

인터넷 익스플로러에서 XHTML을 사용할 수 있는가?

불가능하다. 익스플로러가 application/xhtml+xml MIME 타입을 지원하지 않으므로 이런 헤더 정보를 받게 되면 해당 페이지를 다운로드하려고 한다. 레지스트리를 변경해서(hack) 이 MIME 타입을 인식하도록 할 수는 있지만 그렇다고 해도 해당 문서는 여전히 HTML로 취급된다.

XHTMLXML 기능이 필요하다면 문서를 application/xml로 제공할 수 있다. 인터넷 익스플로러도 이 MIME 타입을 지원하지만 XHTML의 이름 영역(namespace)를 사용할 수 없으므로 해당 문서는 보통의 XML 문서로 인식된다. 따라서 스타일시트가 기본적으로 적용되지 않으므로, 모든 요소에 대한 스타일을 전부 지정해줘야 한다. 예를 들어서 모든 블록 레벨의 요소들에 display: block 속성을 지정해야 한다.

물론 XHTMLtext/html로 제공할 수 있다. 하지만 앞서 길게 설명했던 것처럼 브라우저는 그 XHTML 문서를 문법 오류가 있는 HTML 문서로 인식한다.

† 여기서 말하는 문법 오류는 닫는 태그 앞에 공백과 슬래시 기호가 있는 것을 의미합니다. 예를 들어서 <br /> 태그 같은 것이지요.

인터넷 익스플로러 7은 XHTML을 제대로 지원하는가?

그렇지 않다.


마지막 질문에 대한 짧은 답이 인상적입니다.

간단하게 요약하자면 브라우저가 XHTML을 제대로 지원하지 않고, XHTMLHTML의 기능이 완벽하게 호환되지 않으므로 대부분의 XHTML 문서는 HTML과의 하위 호환성을 고려해서 작성된다는 얘기입니다. 그렇게 작성된 문서에 XML을 지원하는 브라우저에서만 해석 가능한 마크업이 들어갈 리 없으니 겉모습은 XHTML이라도 실제로는 HTML과 다를 바 없다는 것이 원문의 주장입니다.

다음 글에서는 그럼에도 불구하고 XHTML이 널리 사용되는 이유와 마지막으로 발표된 W3C의 XHTML 규격인 XHTML 1.1에 대해서 알아보도록 하겠습니다.

마지막으로 사용자가 자신의 웹 페이지를 요청했을 때 서버가 어떻게 답하는지 궁금한 분들은 W3C의 HTTP Head 서비스를 이용해 보시기 바랍니다. 제 블로그를 확인해 보니 아래 결과가 나오더군요.

200 OK
X-Powered-By: PHP/4.4.2AnNyung
Server: Apache  -OOPS Development Organization-
Connection: close
Date: Thu, 24 May 2007 11:56:37 GMT
P3p: CP='CAO PSA CONi OTR OUR DEM ONL'
Content-Type: text/html; charset=utf-8

마지막 줄에 있는 Content-Type: text/html; charset=utf-8은 제가 이용하고 있는 비누넷 호스팅 서버의 기본 설정입니다. XHTML 문서의 메타 태그로는 바꿀 수 없다는 것에 주의하세요.

관련 글 안내

  1. XHTMLHTML의 차이
  2. 브라우저가 XHTML을 해석하는 방식
  3. XHTML 1.1 규격의 용도와 호환성
  4. XHTML을 사용하는 이유

댓글 6개가 달렸습니다. 태그: , ,

  1. 1UP | 2007-05-24 22:47

    결국은 또 브라우저 문제..-_-
    사실 XHTML2.0, HTML5 이런것 들 보다 브라우저좀 어떻게 해 줬으면 좋겠어요..
    당장 뭘 만들래도 핵질이나 해야 되고..ㅜㅜ

  2. wystan | 2007-05-24 23:23

    W3C의 권고안을 정확히 지키는 브라우저를 만드는 것이 생각보다 훨씬 어려운가 봅니다. 기술적인 문제와 일관성이 없는 W3C의 일부 규격, 그리고 알 수 없는 여러 문제들의 절묘한 조화 때문이겠지요. ^^;

    그래도 익스플로러 5.0 버전 때보다 많이 향상되었으니 시간이 지나면 나아지리라 생각합니다. 긍정적으로… ^^

  3. nuzl | 2007-05-26 03:57

    핵질…-_-; 핵질 없인 뭔가 할수 없는 현실;

  4. wystan | 2007-05-26 10:35

    한 분도 아니고 두 분이나 ‘핵질’이라는 표현을 쓰셨길래 혹시 새로 생긴 신조어가 아닌가 해서 ‘핵질+브라우저’로 구글을 검색해 봤습니다.

    결과가 없더군요! 1UP님께서 이 표현을 처음 사용하셨나 봅니다. 이거 혹시 유행이 되지 않을까요? ^^

  5. 이세조 | 2008-08-16 14:32

    ‘핵질’ 이라는 표현이 브라우저 핵을 말하는듯 한데요?? 아닐까요 ^^;;;
    개별 브라우져 별로 다르게 표현되는 걸 동일하게 표현하기 위한 일종의 편법으로 알고 있는데;;;
    css에
    div.aaaa{
    width:100px;
    padding:20px;
    } * html div.aaaa{
    width:140px;
    padding:20px;
    }
    이렇게 해주어야 IE 에서도 의도한 대로 모양세가 나오듯이… javascript에서도 XMLHttpRequest 객체를 받아 오는 법이 IE에서는 다르기 때문에 비슷한 짓을 해야 하는 것 처럼요..
    보통 IE 에만 hack을 하면 대체적으로 잘 돌아간다고 알고 있는데..
    아닐까요??

  6. wystan | 2008-08-17 15:08

    맞습니다. ^^

    IE 7 이하 버전은 일부 독자적인 방식(hasLayout 모델)을 사용해서 페이지를 렌더링하기 때문에 크로스 브라우징을 위해서 어쩔 수 없이 핵을 써야만 하는 경우가 있습니다.

    CSS 2.1을 따르는 나머지 브라우저는 대부분 일관적으로 동작하지만, 자체적으로 버그가 존재할 수도 있기 때문에 상황에 따라서 핵이 필요할 수도 있습니다. 타겟팅에 있어서는 conditional comment를 쓸 수 있는 IE보다 더 까다로울 수도 있고요.

    “핵”은 근본적으로 브라우저 렌더링 엔진의 버그를 이용하기 때문에 버그 없는 브라우저에서는 필요가 없겠지만 그게 그렇게 쉽지가 않은 것 같습니다. ^^;

댓글이 닫혔습니다.