달력

12

« 2024/12 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

HTTP 상태 코드, 준비 상태, XMLHttpRequest 객체의 이해

developerWorks

 

JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.

 

 



난이도 : 초급

Brett McLaughlin, Author and Editor, O'Reilly Media Inc.

2006 년 6 월 12 일
2006 년 12 월 12 일 수정

많은 웹 개발자들에게 간단한 요청과 응답을 받는 것은, 사실 필요로 하는 전부이기도 합니다. Ajax를 마스터하고자 하는 개발자들에게는 HTTP 상태 코드, 준비 상태, XMLHttpRequest 객체에 대한 완벽한 이해가 필요합니다. 이 글에서는 다양한 상태 코드들을 보여주고 브라우저가 이를 핸들링하는 방법을 설명합니다.

시리즈 소개


지난 글에서는 , XMLHttpRequest 객체에 대해 구체적으로 소개했다. 이것은 서버측 애플리케이션이나 스크립트에 대한 요청을 핸들하고, 서버측 컴포넌트에서 리턴 데이터를 처리하는 Ajax 애플리케이션의 주요 특징이다. 모든 Ajax 애플리케이션은 XMLHttpRequest 객체를 사용하기 때문에 Ajax 애플리케이션의 작동은 여기에 얼마나 익숙해지냐에 달려있다.

이번에는 지난 글에서 다루었던 기초를 넘어서 요청 객체의 세 가지 핵심 부분들에 대해 자세히 설명하겠다.

  • HTTP 준비 상태
  • HTTP 상태 코드
  • 요청 유형들

이들 각각은 요청이라는 배관의 일부로 간주된다. 결국, 작은 상세가 이러한 주제들에 대해 기록된다. 하지만 Ajax 프로그래밍을 염두하고 있다면 준비 상태, 상태 코드, 요청에 익숙해 져야 한다. 애플리케이션에서 무엇인가 잘못되고 있다면 준비 상태, HEAD 요청을 하는 방법, 또는 400 상태 코드가 의미하는 것이 무엇인지를 이해하면 5분의 디버깅으로 끝낼 수 있거나 5시간 동안 좌절과 혼돈 속에서 방황할 수 있다.

XMLHttpRequest 또는 XMLHttp: 또 다른 이름의 장미

Microsoft™와 Internet Explorer는 Mozilla, Opera, Safari, 비 Microsoft 계열 브라우저에서 사용되는 XMLHttpRequest 객체 대신 XMLHttp 라는 객체를 사용한다. 단순하게 하기 위해서 이 두 가지 객체 모두 XMLHttpRequest로 칭하기로 한다. 웹을 검색하다 보면 이런 경우가 비일비재 하고 마이크로소프트도 Internet Explorer 7.0의 요청 객체의 이름으로 XMLHttpRequest를 사용하고 있다. (Part 2 참조)

HTTP 준비 상태 먼저 보도록 하자.

HTTP 준비 상태

지난 글에서 XMLHttpRequest 객체는 readyState 라는 속성을 갖고 있다고 설명했다. 이 속성은 서버가 요청을 완료하고 콜백 함수가 그 서버에서 온 데이터를 사용하여 웹 폼이나 페이지를 업데이트 하도록 한다. Listing 1은 이것에 대한 예제이다.(참고자료)


Listing 1. 콜백 함수에서 서버의 응답 처리하기
				
 function updatePage() {
   if (request.readyState == 4) {
     if (request.status == 200) {
       var response = request.responseText.split("|");
       document.getElementById("order").value = response[0];
       document.getElementById("address").innerHTML =
         response[1].replace(/\n/g, "<br />");
     } else
       alert("status is " + request.status);
   }
 }

이것은 전형적인 준비 상태의 사용법이다. "4"라는 숫자에서 짐작하듯 여러 가지 다른 준비 상태들이 있다.(참고자료)

  • 0: (open()을 호출하기 전에는) 요청이 초기화 되지 않는다.
  • 1: (send()를 호출하기 전에는) 요청은 설정은 되지만 보내지지 않는다.
  • 2: 요청이 보내지고 처리 중에 있다. (이 시점에서 응답에서 콘텐트 헤더를 얻을 수 있다.)
  • 3: 요청이 처리 중에 있다. 부분적인 데이터를 응답에서 사용할 수 있지만 서버는 이 응답으로는 종료되지 않는다.
  • 4: 응답이 완료된다. 서버의 응답을 받고 이를 사용한다.

Ajax 프로그래밍의 기초 이상으로 넘어가고 싶다면 이러한 상태 뿐만 아니라 이들이 언제 발생하고 어떻게 사용하는지에 대해 알아야 한다. 우선, 가장 중요한 것은 어떤 요청 상태가 될 것인지를 배워야 한다. 이는 별로 기분 좋은 일이 아니고 몇 가지 특별한 경우가 포함되어 있다.

숨어있는 준비 상태

readyState 0 (readyState == 0)으로 표시되는 첫 번째 준비 상태는 초기화 되지 않은 요청을 나타낸다. 요청 객체에 대해 open()을 호출하면 속성은 1로 설정된다. 대부분 요청을 초기화 하면서 open()을 호출하기 때문에 readyState == 0을 보는 일은 드물다. 더욱이 초기화 되지 않은 준비 상태는 실제 애플리케이션에서는 쓸모 없다.

Listing 2를 보면 0으로 설정된 준비 상태가 되는 방법을 알 수 있다.


Listing 2. 준비 상태 0
				
   function getSalesData() {
     // Create a request object
     createRequest();		
     alert("Ready state is: " + request.readyState);

     // Setup (initialize) the request
     var url = "/boards/servlet/UpdateBoardSales";
     request.open("GET", url, true);
     request.onreadystatechange = updatePage;
     request.send(null);
   }

이 간단한 예제에서 getSalesData()는 웹 페이지가 요청을 시작하기 위해 호출하는 함수이다. (예를 들어, 버튼이 클릭 될 때.) open()이 호출되기 전에 준비 상태를 체크 해야 한다. 그림 1은 이 애플리케이션을 실행한 결과이다.


그림 1. 준비 상태 0
A ready state of 0
0이 4와 같을 때

다중 JavaScript 함수들이 같은 요청 객체를 사용하는 경우, 그 요청 객체가 사용되고 있지 않다는 것을 확인하기 위해 준비 상태 0을 확인하면 문제가 많아질 수 있다. readyState == 4는 완료된 요청을 나타내기 때문에, 4로 설정된 준비 상태인 채로 사용되지 않은 요청 객체를 종종 보게 된다. abort()이라고 하는 요청 객체를 리셋하는 함수가 있지만 이는 여기에 사용하는 것이 아니다. 다중 함수들을 사용해야 한다면 다중 함수에 객체를 공유하는 것 보다 각 함수용 요청 객체를 생성 및 사용하는 것이 낫다.

분명히 이것은 좋지 않다. open()이 호출되지 않았다는 것을 확인해야 한다. 실제 Ajax 프로그래밍에서 이러한 준비 상태의 유일한 사용은 다중 함수들에 같은 XMLHttpRequest 객체를 사용하여 다중 요청을 만드는 경우이다. 그러한 상황에서, 여러분은 요청 객체가 새로운 요청을 만들기 전에 초기화 되지 않은 상태(readyState == 0)에 있다는 것을 확인해야 한다. 이로서 또 다른 함수가 동시에 객체를 사용하는 것을 방지할 수 있다.

진행중인 요청의 준비 상태 보기

0 준비 상태 외에 요청 객체는 전형적인 요청 응답에서 또 다른 준비 상태를 경험하게 된다. 그리고 마지막으로는 준비 상태 4로 끝난다. 이 때는 대부분의 콜백 함수에서 if (request.readyState == 4)가 된다. 서버가 완료되고 웹 페이지를 업데이트 하거나 서버에서 받은 데이터를 기반으로 액션을 취하는 시기이다.

프로세스를 실제로 보는 것은 간단하다. 준비 상태가 4 라면 콜백에서 단순히 코드를 실행시키는 것 대신 콜백이 호출될 때 마다 준비 상태를 출력한다.(Listing 3)


Listing 3. 준비 상태 점검
				
   function updatePage() {
     // Output the current ready state
     alert("updatePage() called with ready state of " + request.readyState);
   }

이것이 어떻게 실행되는지 확실히 모르겠다면 웹 페이지에서 호출할 함수를 만들고 서버측 컴포넌트로 요청을 보내도록 한다.(Listing 2) 요청을 설정할 때 콜백 함수를 updatePage()로 설정한다. 요청 객체의 onreadystatechange 속성을 updatePage()로 설정한다.

이 코드는 onreadystatechange가 정확히 무엇을 의미하는지 잘 보여주고 있다. 요청의 준비 상태가 변할 때 마다 updatePage()가 호출되고 경고를 받는다. 그림 2는 호출되는 함수의 샘플이다. 이 경우 준비 상태는 1이다.


그림 2. 준비 상태 1
A ready state of 1

코드를 직접 실행해 보라. 웹 페이지에 넣고 이벤트 핸들러를 활성화 한다. (버튼을 누르거나, 요청을 실행하기 위해 설정하는 모든 메소드를 사용하라.) 콜백 함수는 여러 번 실행될 것이다. 요청의 준비 상태가 변할 때 마다 각 준비 상태에 대한 경고를 보게 된다. 이는 각 단계를 통해 요청을 따라가는 최상의 방법이다.

브라우저 차이

이 프로세스에 대해 기본적인 개념이 쌓였다면 여러 가지 다양한 브라우저에서 웹 페이지로 액세스 해보라. 준비 상태가 처리되는 방식에 차이가 있을 것이다. 예를 들어, Firefox 1.5에서, 준비 상태는 다음과 같다.

  • 1
  • 2
  • 3
  • 4

요청의 각 단계들이 다 나타나기 때문에 놀랍지도 않다. 하지만 Safari를 사용하여 같은 애플리케이션에 액세스 하면 재미있는 것을 발견하게 된다. 다음은 Safari 2.0.1에서 보게 되는 상태이다.

  • 2
  • 3
  • 4

Safari는 첫 번째 준비 상태를 배제하고 그 이유에 대해서는 자세히 나와있지 않다. 바로 이것이 Safari 방식이다. 또한 중요한 포인트이기도 하다. 서버에서 데이터를 사용하기 전에 요청의 준비 상태가 4라는 것을 확인하는 것은 좋은 생각인 반면 일시적인 준비 상태에 의존하는 코드를 작성하는 것은 다른 브라우저 마다 다른 결과를 얻을 수 있는 확실한 방법이다.

예를 들어, Opera 8.5를 사용할 때 상황은 더 악화된다.

  • 3
  • 4

Internet Explorer는 다음과 같은 상태로 반응한다.

  • 1
  • 2
  • 3
  • 4

요청과 관련하여 문제가 있다면 문제의 원인을 찾을 수 있는 첫 번째 장소이다. 요청의 준비 상태를 보여주는 경고를 추가하여 상황이 정상적으로 돌아가는지를 확인할 수 있다. Internet Explorer와 Firefox 모두 테스트 하면 네 개의 모든 준비 상태를 얻을 수 있고 각 요청 단계를 검사할 수 있다.

이제는 응답 쪽을 살펴보도록 하자.

응답 데이터

요청 동안에 다양한 준비 상태가 발생할 수 있다는 것을 이해했다면 XMLHttpRequest객체의 또 다른 중요한 부분에 대해 살펴보도록 하자. 바로 responseText 속성이다. 이것은 서버에서 데이터를 얻을 때 사용되는 속성이다. 서버가 요청 처리를 완료하면 그 요청에 응답하는데 필요한 데이터를 요청의 responseText에 둔다. 그런 다음 콜백 함수가 그 데이터를 사용한다.(Listing 1Listing 4 참조)


Listing 4. 서버에서 응답 사용하기
				
   function updatePage() {
     if (request.readyState == 4) {
       var newTotal = request.responseText;
       var totalSoldEl = document.getElementById("total-sold");
       var netProfitEl = document.getElementById("net-profit");
       replaceText(totalSoldEl, newTotal);

       /* Figure out the new net profit */
       var boardCostEl = document.getElementById("board-cost");
       var boardCost = getText(boardCostEl);
       var manCostEl = document.getElementById("man-cost");
       var manCost = getText(manCostEl);
       var profitPerBoard = boardCost - manCost;
       var netProfit = profitPerBoard * newTotal;

       /* Update the net profit on the sales form */
       netProfit = Math.round(netProfit * 100) / 100;
       replaceText(netProfitEl, netProfit);
     }

Listing 1은 매우 간단하다. Listing 4는 좀 더 복잡하다. 시작하려면 준비 상태를 검사하고 responseText 속성에서 값을 얻어야 한다.

요청하는 동안 응답 텍스트 보기

준비 상태와 마찬가지로 responseText 속성의 값은 요청의 수명 주기에 걸쳐 변화한다. Listing 5의 코드를 사용하여 요청의 응답 텍스트를 테스트한다. 준비 상태도 마찬가지로 테스트 한다.


Listing 5. responseText 속성 테스트 하기
				
   function updatePage() {
     // Output the current ready state
     alert("updatePage() called with ready state of " + request.readyState +
           " and a response text of '" + request.responseText + "'");
     }

브라우저에서 웹 애플리케이션을 열고 요청을 활성화 한다. 이 코드를 최대한 활용하려면 Firefox나 Internet Explorer를 사용한다. 이 두 개의 브라우저는 요청 동안 모든 준비 상태들을 보고하기 때문이다. 준비 상태 2에서 responseText 속성은 정의되지 않는다.(그림 3) JavaScript 콘솔이 열려있었다면 에러가 생겼을 것이다.


그림 3. 준비 상태 2의 응답 텍스트
Response text with a ready state of 2

준비 상태 3에서, 서버는 responseText 속성에 값을 배치한다.(그림 4)


그림 4. 준비 상태 3의 응답 텍스트
Response text with a ready state of 3

준비 상태 3의 응답은 스크립트 마다, 서버 마다, 브라우저 마다 다르다. 애플리케이션을 디버깅 하는데 매우 유용하다.

안전한 데이터 얻기

모든 문서와 스팩들에서는 준비 상태가 4가 되어야지만 데이터를 안전하게 사용할 수 있다고 나와있다. 나를 믿으라. 준비 상태가 3일 때에도 responseText 속성에서 데이터를 얻을 수 있다. 하지만 여러분의 애플리케이션에서 이것에 의존하는 것은 좋지 않은 생각이다. 준비 상태 3에서 완전한 데이터에 의존하는 코드를 작성하는 것은 데이터가 불완전하다는 증거이다.

준비 상태가 3일 때 사용자에게 피드백을 제공하는 것이 좋은 생각이다. alert() 같은 함수를 사용하는 것은 좋지 않다. Ajax를 사용하고 사용자와 경고 다이얼로그 박스를 차단시키는 것은 좋지 않지만 준비 상태가 변할 때 마다 폼이나 페이지에 대한 필드를 업데이트 할 수 있다. 예를 들어, 프로그레스 인디케이터의 넓이를 준비 상태 1에 25 퍼센트, 준비 상태 2에 50 퍼센트, 준비 상태 3에 75 퍼센트, 준비 상태 4에 100 퍼센트를 설정한다.

물론 알다시피, 이 방식은 좋기는 하지만, 브라우저에 의존적이다. Opera에서는 첫 번째 두 개의 준비 상태를 결코 얻지 못하고 Safari는 처음 1 상태를 누락시킨다.

이제 상태 코드에 대해 알아보자.

HTTP 상태 코드

Ajax 프로그래밍 기술에서 준비 상태와 서버의 응답 외에도, Ajax 애플리케이션에 또 다른 고급 레벨을 추가할 수 있다. 바로 HTTP 상태 코드이다. 이 코드들은 Ajax에서는 새우울 것이 없다. 웹에 있는 한 언제나 존재하는 것들이다. 웹 브라우저를 통해 이들을 보았을 것이다.

  • 401: Unauthorized
  • 403: Forbidden
  • 404: Not Found

이 외에도 더 있다.(참고자료) Ajax 애플리케이션에 또 다른 제어 및 응답 레이어를 추가하려면 요청과 반응에 상태 코드를 검사해야 한다.

200: Everything is OK

많은 Ajax 애플리케이션에서 준비 상태를 점검하고 서버 응답으로 온 데이터로 작업하는 콜백 함수를 볼 수 있다.(Listing 6)


Listing 6. 상태 코드를 무시하는 콜백 함수
				
   function updatePage() {
     if (request.readyState == 4) {
       var response = request.responseText.split("|");
       document.getElementById("order").value = response[0];
       document.getElementById("address").innerHTML =
         response[1].replace(/\n/g, "<br />");
     }
   }

이것은 근시안적이고 에러를 많이 만드는 Ajax 프로그래밍 방식이다. 스크립트가 인증을 필요로 하는데 요청이 유효 증명을 제공하지 않으면 서버는 403 또는 401 같은 에러를 리턴한다. 하지만 서버가 요청에 응답하기 때문에 준비 상태는 4로 설정될 것이다. 결과적으로 사용자는 유효 데이터를 얻지 못하고 JavaScript가 존재하지 않는 서버 데이터를 사용하려고 할 때 에러를 얻게 된다.

서버가 요청을 완료하고 "Everything is OK" 상태 코드를 리턴했다는 것을 확인하는 것은 간단한 일이다. 이 코드는 "200"이고 XMLHttpRequest 객체의 status 속성을 통해서 보고된다. 서버가 요청으로 끝나고 OK 상태를 리포트 했다는 것을 확인하려면 추가 체크를 콜백 함수에 추가한다.(Listing 7)


Listing 7. 유효 상태 코드 추가
				
   function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         var response = request.responseText.split("|");
         document.getElementById("order").value = response[0];
         document.getElementById("address").innerHTML =
           response[1].replace(/\n/g, "<br />");
       } else
         alert("status is " + request.status);
     }
   }

코드에 몇 줄을 추가하는 것으로 무엇이 잘못되었는지를 알 수 있고 사용자는 아무런 설명이 없는 데이터 데신 유용한 에러 메시지들을 받을 수 있다.

리다이렉션과 재 라우팅

에러에 대해 이야기 하기 전에 Ajax를 사용할 때 걱정하지 않아도 될 부분에 대해 말해두겠다. 바로 리다이렉션이다. HTTP 상태 코드에서, 이것은 300 대의 상태 코드이다.

  • 301: Moved permanently
  • 302: Found (요청이 또 다른 URL/URI로 리다이렉션 된다.)
  • 305: Use Proxy (요청은 프록시를 사용하여 요청 받은 리소스에 액세스 해야 한다.)

Ajax 프로그래머가 리다이렉션에 대해 염려 할 필요가 없는 이유가 두 가지 있다.

  • Ajax 애플리케이션들은 특정 서버측 스크립트, 서블릿, 애플리케이션을 위해 작성된다. 그 컴포넌트를 없애거나 다른 곳으로 이동하기 위함이다. 리소스는 변경되었다는 것을 (이미 이동했기 때문에)알고, 요청에서 URL을 변경하고 이러한 종류의 결과를 절대 만나지 않게 된다.
  • 보다 관련성 있는 이유가 있다. Ajax 애플리케이션과 요청들은 샌드박스화 되어있다. Ajax 요청을 만드는 웹 페이지를 공급하는 도메인은 그러한 요청에 응답해야 하는 도메인이다. 따라서 ebay.com에서 공급 받은 웹 페이지는 Ajax 스타일의 요청을 amazon.com에서 실행되는 스크립트에 할 수 없다. ibm.com 상의 Ajax 애플리케이션은 netbeans.org에서 실행되는 서블릿으로 요청할 수 없다.

결국, 요청은 보안 에러를 만들지 않고서는 또 따른 서버로 리다이렉션 될 수 없다. 그러한 경우에, 상태 코드를 전혀 얻을 수 없다. 디버그 콘솔에 JavaScript 에러를 갖게 된다. 따라서 많은 상태 코드에 대해 생각하는 동안 리다이렉션 코드 정도는 무시할 수 있는 것이다.

엣지 케이스와 하드 케이스

이 부분에서, 신참 프로그래머들은 이러한 혼란에 대해 궁금할 것이다. Ajax 요청의 5 퍼센트 정도는 2와 3 정도의 준비 상태와 403 같은 상태 코드로 작동해야 한다. (사실, 1 퍼센트 미만이다.) 이러한 케이스는 중요하고, 엣지 케이스(edge cases)라고 일컬어진다. 이상한 조건들이 부합되는 특수한 상황인 것이다. 일상적인 것은 아니지만 사용자를 곤란에 처하게 한다.

일반적인 사용자들은 애플리케이션이 정확히 작동하는지 매번 잊지만 그렇지 않을 때는 분명히 기억한다. 엣지 케이스와 하드 케이스를 핸들 할 수 있다면 사이트 사용자들을 만족시킬 수 있을 것이다.

에러

일단, 상태 코드 200을 관리했고 300 계열의 상태 코드는 대충 무시하면 다양한 유형의 에러들을 나타내는 400 계열의 코드만 남게 된다. Listing 7을 보면 에러가 처리되는 동안 사용자에게 출력되는 매우 일반적인 에러 메시지라는 것을 알게 된다. 이것은 올바른 방향으로 가는 단계지만 사용자와 프로그래머에게는 매우 쓸모없는 메시지이다.

우선 소실된 페이지에 대한 지원을 추가한다. 이는 제품 시스템에서는 실제로 발생하지는 않지만 스크립트를 이동시키는 테스트나 정확하지 않은 URL을 입력할 때 자주 일어나는 일이다. 404 에러를 보고하면 혼란스러워 하는 사용자와 프로그래머에게 더 많은 도움말을 제공할 것이다. 예를 들어, 서버 상의 스크립트가 제거되거나 Listing 7에서 그 코드를 사용하면 다음과 같은 에러가 생긴다.(그림 5)


그림 5. 일반적인 에러 핸들링
Generic error handling

사용자는 문제가 무엇인지 잘 모른다. 인증에 관련된 것인지, 소실된 스크립트 인지, 사용자 에러인지 알 수 없다. 몇 가지 간단한 코드 추가로 이 에러는 더욱 구체화 된다. Listing 8을 보면 소실된 스크립트와 인증 에러까지 구체적인 메시지와 함께 처리된다.


Listing 8. 유효 상태 코드 점검
				
   function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         var response = request.responseText.split("|");
         document.getElementById("order").value = response[0];
         document.getElementById("address").innerHTML =
           response[1].replace(/\n/g, "<br />");
       } else if (request.status == 404) {
         alert ("Requested URL is not found.");
       } else if (request.status == 403) {
         alert("Access denied.");
       } else
         alert("status is " + request.status);
     }
   }

이는 오히려 더 간단하지만 추가 정보 까지 제공한다. 그림 6그림 5와 같은 에러를 보여주지만 이번에는 에러 핸들링 코드가 더 나은 그림을 제공하고 있다.


그림 6. 구체적인 에러 핸들링
Specific error handling

여러분의 애플리케이션에서 인증 때문에 오류가 발생했을 때 사용자 이름과 패스워드를 지우고 에러 메시지를 스크린에 추가하는 것을 고려할 수도 있다. 이와 비슷한 방식이 소실된 스크립트나 다른 400 유형의 에러들을 핸들하는데 사용될 수 있다. 여러분이 어떤 선택을 하든 서버에서 리턴 된 상태 코드를 핸들하는 것으로 시작한다.

추가 요청 유형

XMLHttpRequest 객체를 제어하고 싶다면 HEAD 요청을 레파토리에 추가하라. 이전 두 개의 기사에서 GET 요청을 하는 방법을 설명했다. 앞으로는 POST 요청을 사용하여 서버로 데이터를 보내는 것을 설명하도록 하겠다. 향상된 에러 핸들링과 정보 수집을 위해 HEAD 요청에 대해 배워야 한다.

요청하기

HEAD 요청은 실제로 매우 간단하다. 첫 번째 매개변수로서 "GET" 또는 "POST" 대신 "HEAD"로 open() 메소드를 호출한다.(Listing 9)


Listing 9. HEAD 요청
				
   function getSalesData() {
     createRequest();
     var url = "/boards/servlet/UpdateBoardSales";
     request.open("HEAD", url, true);
     request.onreadystatechange = updatePage;
     request.send(null);
   }

이와 같이 HEAD 요청을 하면 서버는 GET이나 POST 요청 때 처럼 실제 응답을 리턴하지 않는다. 대신, 서버는 응답에 있는 콘텐트가 마지막으로 수정된 시간이 포함된 리소스의 헤더를 리턴한다. 게다가 몇 가지 재미있는 정보도 추가한다. 이들을 사용하여 서버가 리소스를 처리 및 리턴하기 전에 리소스에 대해 알 수 있다.

이와 같은 요청으로 할 수 있는 가장 쉬운 일은 모든 응답 헤더들을 나누는 것이다. 이로서 HEAD 요청을 통해 무엇이 가능한지를 알 수 있다. Listing 10은 HEAD 요청에서 모든 응답 헤더를 출력하는 콜백 함수이다.


Listing 10. HEAD 요청에서 모든 응답 헤더 프린트 하기
				
   function updatePage() {
     if (request.readyState == 4) {
       alert(request.getAllResponseHeaders());
     }
   }

그림 7에서 서버에 HEAD 요청을 한 간단한 Ajax 애플리케이션에서 온 응답 헤더를 볼 수 있다.


그림 7. HEAD 요청에서 온 응답 헤더
Response headers from a HEAD request

이러한 헤더들을 개별적으로 사용하여 Ajax 애플리케이션에서 추가 정보나 기능을 제공할 수 있다.

URL 검사

URL이 존재하지 않을 때 404 에러를 검사하는 방법을 이미 보았다. 이것이 일반적인 문제라면, 특정 스크립트나 서블릿이 잠시 동안 오프라인에 있었다면, GET 또는 POST 요청을 하기 전에 URL을 검사해 보는 것이 좋다. HEAD 요청을 하고 콜백 함수에서 404 에러를 검사한다. Listing 11은 샘플 콜백을 보여준다.


Listing 11. URL이 존재하는지 여부 검사
				
   function updatePage() {
     if (request.readyState == 4) {
       if (request.status == 200) {
         alert("URL exists");
       } else if (request.status == 404) {
         alert("URL does not exist.");
       } else {
         alert("Status is: " + request.status);
       }
     }
   }

솔직히 말하면 이것의 가치는 별로 없다. 서버는 요청에 응답해야 하고 응답을 분석하여 응답 헤더에 파퓰레이트 하기 때문에 여러분은 프로세싱 시간을 저축할 수 없다. 게다가 요청을 하고 HEAD 요청을 사용하여 URL이 존재하는지 보는 것에도 많은 시간이 걸린다. Listing 7에서 처럼 에러를 핸들링 하기 보다 GET이나 POST를 사용하여 요청하기 때문이다. 무엇을 사용할 수 있는지를 정확히 아는 데는 가끔 유용하다.

유용한 HEAD 요청

HEAD 요청이 유용한 한 가지 부분은 콘텐트 길이나 콘텐트 유형을 검사할 때이다. 요청을 처리하기 위해 많은 양의 데이터를 보낼 것인지, 서버가 HTML, 텍스트, XML 대신 바이너리 데이터를 리턴해야 할지를 결정할 수 있다. (이 세 가지 모두 바이너리 데이터 보다 JavaScript에서 처리하는 것이 더 쉽다.)

이 경우, 적절한 헤더 이름을 사용하고 이를 XMLHttpRequest 객체의 getResponseHeader() 메소드로 보낸다. 따라서 응답의 길이를 알려면 request.getResponseHeader("Content-Length");를 호출한다. 콘텐트 유형을 알려면 request.getResponseHeader("Content-Type");를 사용한다.

많은 애플리케이션에서 HEAD 요청을 하면 어떤 기능도 추가하지 않고 요청의 속도를 늦출 수 있다. (HEAD 요청을 실행하여 응답에 대한 데이터를 얻고 후속 GET 또는 POST 요청을 통해 응답을 실제로 받는다.) 하지만 스크립트나 서버측 컴포넌트에 대해 확실하지 않은 경우 HEAD 요청으로 기본적인 데이터를 받을 수 있다.

결론

Ajax와 웹 프로그래머에게 이 글은 다소 어려울 것이다. HEAD 요청을 하는 것의 가치는 무엇인가? JavaScript에서 리다이렉션 상태 코드를 핸들해야 하는 때는 언제인가? 이 모두 좋은 질문이다. 간단한 애플리케이션의 경우, 이 모든 것은 가치가 별로 없다.

하지만 웹이 단순한 애플리케이션만 수용하는 것은 아니다. 사용자는 점점 고급화 되고 고객들도 강력한 에러 리포팅을 원한다. 관리자 역시 애플리케이션이 조금만 느려져도 해고를 당하게 된다.

간단한 애플리케이션을 넘어 XMLHttpRequest에 대한 이해를 높여야 할 때이다.

  • 다양한 준비 상태를 이해하고 이들이 브라우저 마다 어떻게 다른지를 이해하면 애플리케이션을 빠르게 디버깅 할 수 있다. 준비 상태에 기반하여 창조적인 기능을 만들고 요청자의 상태에 대해 사용자와 고객에게 보고할 수 있다.
  • 상태 코드를 핸들했다면 스크립트 에러, 예기치 못한 응답들, 엣지 케이스들을 다룰 수 있다. 결국, 애플리케이션은 언제나 잘 작동될 것이다.
  • 여기에 더하여 HEAD 요청을 만들고, URL의 존재를 검사하고 파일이 언제 수정되었는지를 파악하고 사용자가 유효 페이지를 얻었는지를 확인할 수 있다면 언제나 최신의 정보와 강력한 기능으로 사용자들을 만족시킬 수 있을 것이다.

이들은 모두 Ajax의 강점이지만 극히 일부분이다. Ajax를 사용하여 애플리케이션이 에러와 문제들을 부드럽게 해결할 수 있는 강력한 토대를 구현한다면 사용자는 여러분의 사이트를 방문할 것이다. 다음 글에서는 보다 더 재미있고 흥미 있는 주제들을 나누도록 하겠다.

기사의 원문보기





위로


다운로드 하십시오

설명 이름 크기 다운로드 방식
Example code for this article wa-ajaxintro3_ajax-xhr_adv.zip 183KB HTTP
다운로드 방식에 대한 정보 Get Adobe® Reader®


참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Brett McLaughlin

Brett McLaughin은 Logo 시절부터 컴퓨터 업계에서 일했다 (작은 트라이앵글 기억하는가?). 최근에 그는 Java 및 XML 커뮤니티에서 인기 저자 및 프로그래머가 되었다. Nextel Communication사에서는 복잡한 기업 시스템 실행에 관한 업무, Lutris Technologies 사에선 애플리케이션 서버를 실지로 작성하는 업무, 최근 O’Reilly Media 사에서는 이와 관련된 중요한 책을 저술, 편집했다. Brett의 최근 저서인 Head Rush Ajax는 Ajax에 관한 혁신적인 연구에 기여, 공동저자인 Eric 및 Beth Freeman과 함께 공동으로 수상했다. 그의 최근 저서인 Java 1.5 Tiger: A Developer's Notebook은 신 자바 기술 버전 상에서 이용 가능한 첫 번째 저서다. Brett의 최신 Java 및 XML은 자바언어에서 XML 기술을 활용한 명백한 업적 중 하나로 남아 있다.

:
Posted by 뽀기