X-Requested-With header

발생일: 2011.12.19

문제:
종종 어떤 서비스들의 Ajax 패킷을 보다보면,
X-Requested-With 헤더에 XMLHttpRequest 값이 포함된 걸 볼 수 있다.

Ajax로 요청하는 트위터의 타임라인을 예로 들어보면,
아래와 같이 요청 헤더에 X-Requested-With 헤더가 있다.

  GET /1/statuses/home_timeline.json?...  HTTP/1.1
  Host: api.twitter.com
  Connection: keep-alive
  X-Requested-With: XMLHttpRequest
  User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 Safari/535.11
  ...


정확하게 이 헤더가 의미하는 건 뭐고,
어떤 용도로 사용하는 건지 알아보자.


해결책:

X-Requested-With 헤더는, 해당 요청이 Ajax라는 걸 의미한다.


표준 헤더는 아닌 커스텀 헤더이며,
jQuery와 Prototype을 포함한 대부분의 자바스크립트 라이브러리에서 Ajax 요청을 보낼 때에 이 헤더를 설정한다. 

(여기서, 접두사 X는 표준이 아님을 의미한다. (non-standard))


실제로 jQuery 코드를 보면, 아래와 같이 헤더를 설정하고 있다.

  if ( !( s.crossDomain && !s.hasContent ) && !headers["x-requested-with"] ) {
    headers[ "x-requested-with" ] = "XMLHttpRequest";
  }

(HTTP 헤더는 대소문자를 구분하지 않는다. (case-insensitive하다))


Prototype도 마찬가지이다.

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    }; 



이 커스텀 헤더를 통해 해당 요청이 Ajax 임을 서버에 알려줄 수 있을 뿐 아니라,
JSON Hijacking을 방어하는 용도로 사용할 수도 있다.
실제로 Ruby on Rails나 Django 등 몇몇 서버에서는 이 헤더로 Ajax 요청인지를 구분하는 기능을 제공하기도 한다.


참고로, Rails에 구현되어 있는 코드는 아래와 같다.

  # Returns true if the "X-Requested-With" header contains "XMLHttpRequest"

  # (case-insensitive). All major JavaScript libraries send this header with
  # every Ajax request.
  def xml_http_request?
    @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
  end
  alias :xhr? :xml_http_request?

(HTTP_X_REQUESTED_WITH 는 x-requested-with 헤더를 의미한다)


X-Requested-With 헤더는 비표준이지만,
대부분의 라이브러리가 사용하고 있기 때문에 실질적인 표준이라 해도 무방할 것 같다.


#. 참고.
List of HTTP header fields Wikipedia:  http://en.wikipedia.org/wiki/List_of_HTTP_header_fields 
Rails github:  https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/http/request.rb#L136
HTTP 1.1 Spec(RFC2616):  http://www.ietf.org/rfc/rfc2616.txt
Custom HTTP Headers: http://www.developertutorials.com/learn-ajax/custom-http-headers-2643.php 
HTTP_X_REQUESTED_WITH in Django: http://stackoverflow.com/questions/458617/x-requested-with-http-x-requested-with-weird-problem




카테고리

분류 전체보기 (730)
About me. (6)
Daylogs (695)
영어공부 (0)
My works - 추억 (29)
비공개 (0)