행복한 아빠

IE가 나를 또 절망시키다 - Accept 헤더 본문

잡다한기록

IE가 나를 또 절망시키다 - Accept 헤더

행복한아빠 2010. 2. 24. 19:03
HTTP 스펙에 충실하여 프로그래밍을 하려고 하는데 브라우저가 저를 또 절망에 빠뜨리는군요. 다른 것이 아니라 content negotiation이라는 걸 한 번 살펴볼라고 합니다.




Content negotiation

HTTP 클라이언트가 서버에 컨텐츠를 요청할 때 HTTP 클라이언트는 서버에 어떤 형식(MediaType)으로 달라는 요청을 할 수 있습니다. HTTP 헤더에 보시면 Accept 헤더가 이걸 뜻합니다.

다음 FireFox HTTP 요청 헤더를 예로 들어봅니다.

GET /book HTTP/1.1
...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
...

이 뜻을 우리말로 풀이하면
책(/book) 정보를 text/html이나 application/xhtml+xml,application/xml 또는 아무 형식으로 주십시오.

여기서 q가 뜻하는 것은 다음과 같습니다. HTTP 스팩의 내용입니다.
Each media-range MAY be followed by one or more accept-params, beginning with the "q" parameter for indicating a relative quality factor. The first "q" parameter (if any) separates the media-range parameter(s) from the accept-params. Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range, using the qvalue scale from 0 to 1 (section 3.9). The default value is q=1.
accept 파라메터의 각각 미디어 범위는 relative quality 인자인 "q" 파라메터로 하나이상 올 수 있다. 첫번째 "q" 파라메터 accept 파라메터의 미디어 범위를 분리한다. Quality 인자는 사용자나 사용자 agent가 선호하는 미디어 범위의 정도를 나타낼 수 있도록 한다. qvalue 범위는 0 에서 1 사이이다. 기본값은 q=1이다.
- 번역의 품질은 보지 마십시오 -.-;
즉 위의 헤더를 다시 한글로 번역하면
책(/book) 정보를 text/html이나 application/xhtml+xml,application/xml 또는 아무 형식으로 주십시오.
그런데 text/html, application/xhtml+xml,application/xml 형식을 더 좋아하고요. 아무 형식은 그 다음 좋아합니다. 뭐 어떤 형식도 받습니다만...

IE 헤더

다음은 IE 7의 Accept 헤더입니다.
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/msword, application/vnd.ms-powerpoint, application/x-silverlight, application/x-silverlight-2-b2, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, */*

특이한 건 application/msword 같이 오피스 형식으로 받고 싶어한다는 요청입니다. text/html 이나 application/xhtml 같이 브라우저에서 기본으로 처리할 미디어 타입은 없습니다. qvalue도 없습니다. 그냥 아무거나 다 받겠다는 겁니다.

Content Negotiation을 이용한 우아한 RESTful 설계 방법

위 예의 책정보(/book)를 경우에 따라 브라우저에서 접속할 경우는 HTML 형식으로 AJAX 호출일 경우에는 XML이나 JSON 형식으로 받고 싶을 경우 Content Negotiation을 이용하여 다음과 같이 HTTP 요청을 설계할 수 있습니다.

브라우저용 HTML 요청
GET /book HTTP/1.1
...
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
...

AJAX용 JSON 요청
GET /book HTTP/1.1
...
Accept: application/json;q=0.9;*/*;q=0.8
...

서버는 이 요청의 Accept 헤더를 분석하여 알맞은 형식으로 서비스를 제공하면 됩니다. 동일한 URI에 디바이스 요청에 따라 알맞은 형식의 컨텐츠 제공... 아주 훌륭한 아이디어이며 이건 HTTP 스팩의 내용입니다.

또한 Content Negotiation을 이용한 위 기능은 Rails, Grails 그리고 제가 사용하고 있는 sun(지금은 오라클)에서 만든 jersey 프레임워크에서 기본으로 지원합니다.

문제점

그런데 가장 많이 쓰고 있다고 알려진 IE에서 text/html이나 application/xhtml 으로 받을 의지가 없어 Content negotiation 은 물건너 간 것 같습니다. 게다가 IE의 Accept 헤더 굉장히 깁니다. (300바이트가 넘네요, 이건 매 요청마다 항상 날아갑니다)

HTTP의 훌륭한 아이디어와 유용한 HTTP 표준 헤더를 쓸모없게 만들고 RESTful 한 멋진 설계를 하려던 내 의지를 아주 긴~ 한 줄의 헤더로 꺽어버린 IE에 박수를 보냅니다.

다른 방법을 찾아봐야겠습니다. ㅠㅠ

오마이 갓~ (2010/02/26)

어떻게든 IE의 예외를 고려해서 처리할려고 했는데 오마이 갓~
IE는 새로고침 F5를 누르면 Accept 헤더가 서버로 다음과 같이 날립니다.
...
Accept: */*
...



1 Comments
  • 프로필사진 거친마루 2011.02.21 01:23 꽤 오래된 글이지만 제가 고민하고 있는 것과 통하는게 있어서 댓글 남깁니다.

    일단 저는 user-agent가 IE 인 경우는 그냥 text/html 을 우선으로 하고 있습니다 ㅠ.ㅜ
    그런데 또 한가지 최근에 one web 에 좀 관심을 두고 디바이스에 따라 다른 화면 구성을 보여주는 것을 하다가, css로 화면 구성만을 바꾸는것으로는 한 화면에 보여질 정보 양을 조절하는게 힘들다는 결론을 내리고 모바일 브라우져일때 자바스크립트의 힘을 약간 빌어 추가로 content negotiate를 할 수 있을까 고민 중입니다.

    일단 Accept: text/html; format=jqtouch 라던가.. 이게 반칙인지 아닌지 찾아보는 중이고요..
    안되면 X-Accept-Html-Template: jqtouch 처럼 비표준 헤더를 쓸 생각입니다.

    IE가 아직도 최대 점유율이라니 씁쓸하네요.. IE9에선 좀 나아지려나요?
댓글쓰기 폼