대부분의 웹 애플리케이션은 요청/응답 모델을 사용하여 서버에서 완전한 HTML 페이지를 얻습니다. 이는 버튼을 클릭하고, 서버가 응답할 때까지 기다리고, 다른 버튼을 클릭하고, 다시 기다리는 반복적인 프로세스인 경우가 많습니다. Ajax와 XMLHttpRequest 객체를 사용하면 사용자가 서버의 응답을 기다릴 필요가 없는 요청/응답 모델을 사용할 수 있습니다. 이 기사에서 Brett McLaughlin은 다양한 브라우저에 적응하고, 요청을 설정 및 보내고, 서버에 응답할 수 있는 XMLHttpRequest 인스턴스를 만드는 방법을 설명합니다.
이 시리즈의 이전 기사(링크는 참고자료 참조)에서 우리는 Ajax 애플리케이션을 소개하고 Ajax 애플리케이션을 구동하는 기본 개념을 조사했습니다. 이것의 핵심에는 JavaScript, HTML, XHTML, 약간의 동적 HTML, DOM(Document Object Model) 등 여러분이 이미 알고 있을 많은 기술이 있습니다. 이 기사에서는 한 지점을 확대하고 특정 Ajax 세부 사항에 중점을 둘 것입니다.
이 기사에서는 Ajax와 관련된 가장 기본적이고 기본적인 객체와 프로그래밍 방법인 XMLHttpRequest 객체를 접하게 될 것입니다. 이 개체는 실제로 모든 Ajax 애플리케이션에 걸쳐 있는 공통 스레드일 뿐이며 예상할 수 있듯이 전체 프로그래밍 잠재력을 실현하려면 이 개체를 철저히 이해해야 합니다. 실제로 XMLHttpRequest를 올바르게 사용하기 위해 XMLHttpRequest를 사용할 수 없는 경우가 있습니다. 무슨 일이야?
Web 2.0 개요
코드를 자세히 살펴보기 전에 최근의 관점을 살펴보겠습니다. Web 2.0의 개념을 명확하게 이해하는 것이 중요합니다. Web 2.0이라는 용어를 들으면 먼저 "Web 1.0이란 무엇입니까?"라고 질문해야 합니다. 사람들이 Web 1.0을 언급하는 경우는 드물지만 실제로 Web 1.0은 완전히 다른 요청 및 응답 모델을 사용하는 전통적인 웹을 의미합니다. 예를 들어 Amazon.com 웹사이트로 이동하여 버튼을 클릭하거나 검색어를 입력합니다. 요청이 서버로 전송되고 응답이 브라우저로 반환됩니다. 요청은 단순한 도서 및 제목 목록이 아니라 또 다른 완전한 HTML 페이지입니다. 따라서 웹 브라우저가 새 HTML로 페이지를 다시 그릴 때 깜박임이나 떨림이 나타날 수 있습니다. 실제로 요청과 응답은 표시되는 모든 새 페이지에서 명확하게 표시됩니다.
웹 2.0은 (대부분) 이러한 눈에 띄는 앞뒤 상호 작용을 제거합니다. 예를 들어, Google Maps 또는 Flickr와 같은 사이트를 방문하십시오(Web 2.0 및 Ajax 지원 사이트에 대한 링크는 참고자료 참조). 예를 들어 Google 지도에서는 최소한의 다시 그리기로 지도를 드래그하여 확대 및 축소할 수 있습니다. 물론 여전히 요청과 응답이 있지만 그 뒤에는 숨겨져 있습니다. 사용자로서 경험은 더욱 편안하고 데스크탑 애플리케이션과 매우 흡사합니다. 이 새로운 느낌과 패러다임은 누군가가 웹 2.0을 언급할 때 얻게 되는 것입니다.
관심은 이러한 새로운 상호 작용을 가능하게 만드는 것입니다. 분명히 여전히 요청을 하고 응답을 받아야 하지만 느리고 투박한 웹 상호 작용의 느낌을 만드는 것은 각 요청/응답 상호 작용에 대해 HTML을 다시 그리는 것입니다. 따라서 전체 HTML 페이지가 아닌 필수 데이터만 포함하는 요청을 보내고 응답을 받는 방법이 필요하다는 것은 분명합니다. 전체 새 HTML 페이지를 가져와야 하는 유일한 경우는 사용자가 새 페이지를 보도록 할 때입니다.
그러나 대부분의 상호 작용은 기존 페이지에 세부 정보를 추가하거나, 주요 텍스트를 수정하거나, 원본 데이터를 덮어씁니다. 이러한 경우 Ajax 및 Web 2.0 방법을 사용하면 전체 HTML 페이지를 업데이트하지 않고도 데이터를 보내고 받을 수 있습니다. 온라인에서 많은 시간을 보내는 사용자의 경우 이 기능을 사용하면 애플리케이션의 속도와 반응성이 향상되어 애플리케이션이 때때로 사이트를 다시 방문하게 됩니다.
XMLHttpRequest 소개
이 놀라운 기적을 진정으로 실현하려면 XMLHttpRequest라는 JavaScript 개체에 대해 잘 알고 있어야 합니다. 이 작은 개체는 실제로 한동안 여러 브라우저에서 사용되었으며 Web 2.0, Ajax 및 앞으로 몇 달 동안 이 칼럼에서 다룰 다른 많은 내용의 핵심입니다. 빠른 개요를 제공하기 위해 이 개체에 사용되는 몇 가지 메서드와 속성은 다음과 같습니다.
·open(): 서버에 대한 새로운 요청을 설정합니다.
·send(): 서버에 요청을 보냅니다.
·abort(): 현재 요청을 중단합니다.
·readyState: 현재 HTML의 준비 상태를 제공합니다.
·responseText: 서버가 반환한 요청 응답 텍스트입니다.
이것들(또는 그 중 하나라도)을 모르더라도 걱정하지 마십시오. 다음 몇 가지 기사에서 각 방법과 속성을 다룰 것입니다. 지금 알아야 할 것은 정확히 XMLHttpRequest로 무엇을 해야 하는지입니다. 이러한 메서드와 속성은 요청 보내기 및 응답 처리와 관련이 있습니다. 실제로 XMLHttpRequest의 모든 메서드와 속성을 살펴보면 모두 매우 간단한 요청/응답 모델과 관련되어 있음을 알 수 있습니다. 분명히 우리는 특별히 새로운 GUI 개체나 사용자 상호 작용을 생성하는 매우 신비한 방법을 접하지 않을 것이며 매우 간단한 요청과 매우 간단한 응답을 사용할 것입니다. 별것 아닌 것처럼 들리겠지만 이 개체를 잘 사용하면 애플리케이션에 혁명을 일으킬 수 있습니다.
간단하게 새로 만들기
위해서는 먼저 새 변수를 만들고 XMLHttpRequest 개체 인스턴스를 할당해야 합니다. 이는 목록 1에 표시된 것처럼 JavaScript의 개체 이름에 new 키워드를 사용하는 것만큼 간단합니다.
목록 1. 새 XMLHttpRequest 개체 만들기
<script 언어="javascript" type="text/javascript">
var 요청 = 새로운 XMLHttpRequest();
</script>
어렵지 않나요? JavaScript에서는 변수 유형을 지정할 필요가 없으므로 목록 2에서 수행하는 작업(Java 언어에서 수행할 수 있음)을 수행할 필요가 없습니다.
목록 2. XMLHttpRequestXMLHttpRequest
요청을 생성하기 위한 Java 의사 코드 = new XMLHttpRequest();
따라서 JavaScript에서는 var를 사용하여 변수를 생성하고 이름(예: "요청")을 지정한 다음 새 XMLHttpRequest 인스턴스를 할당합니다. 그런 다음 객체를 함수에서 사용할 수 있습니다.
오류 처리
모든 종류의 일이 실제로 잘못될 수 있으며 위의 코드는 오류 처리를 제공하지 않습니다. 더 나은 접근 방식은 객체를 생성하고 문제가 발생하면 정상적으로 종료하는 것입니다. 예를 들어, 이전 브라우저(믿거나 말거나, 여전히 이전 버전의 Netscape Navigator를 사용하는 사람들이 있음)는 XMLHttpRequest를 지원하지 않으므로 이러한 사용자에게 뭔가 잘못되었음을 알려야 합니다. 목록 3에서는 문제가 발생할 때 JavaScript 경고를 내보내도록 이 개체를 만드는 방법을 보여줍니다.
목록 3. 오류 처리 기능을 갖춘 XMLHttpRequest 생성하기
<스크립트 언어="자바스크립트" 유형="텍스트/자바스크립트">
var 요청 = 거짓;
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기 (실패) {
요청 = 거짓;
}
if (!request)
Alert("XMLHttpRequest 초기화 오류!");
</script>
다음 단계를 이해하십시오.
1. 새 변수 요청을 생성하고 false 값을 할당합니다. False는 추후 판단 조건으로 사용되는데, 이는 XMLHttpRequest 객체가 아직 생성되지 않았음을 의미합니다.
2. try/catch 블록을 추가합니다.
1) XMLHttpRequest 객체를 생성해보십시오.
2) 실패(catch(실패))한 경우 요청 값이 여전히 거짓임을 보장합니다.
3. 요청이 여전히 거짓인지 확인합니다(모든 것이 정상이면 거짓이 아닙니다).
4. 문제가 발생하면(요청이 false인 경우) JavaScript 경고를 사용하여 문제가 발생했음을 사용자에게 알립니다.
코드는 매우 간단하며 대부분의 JavaScript 및 웹 개발자의 경우 코드를 읽고 작성하는 것보다 코드를 진정으로 이해하는 데 더 오랜 시간이 걸립니다. 이제 오류 검사를 거쳐 무엇이 잘못되었는지 알려줄 수 있는 XMLHttpRequest 객체 생성 코드가 생겼습니다.
적어도 Internet Explorer에서 코드를 시험해 보기 전까지는
Microsoft에서는
모든 것이 괜찮은 것 같습니다.이렇게 실험해 보면 그림 1과 같은 나쁜 상황을 볼 수 있을 것이다.
그림 1. Internet Explorer 보고 오류
뭔가 분명히 잘못된 것이며, Internet Explorer는 전 세계의 70%가 사용하고 있기 때문에 결코 오래된 브라우저가 아닙니다. 즉, Microsoft와 Internet Explorer를 지원하지 않으면 웹 세계에서 인기가 없을 것입니다! 따라서 우리는 Microsoft 브라우저에 대해 다른 접근 방식을 취해야 합니다.
Microsoft가 Ajax를 지원하는 것으로 확인되었지만 XMLHttpRequest 버전의 이름이 다릅니다. 실제로는 여러 가지 다른 이름으로 부릅니다. 최신 버전의 Internet Explorer를 사용하는 경우에는 Msxml2.XMLHTTP 개체를 사용해야 하지만 이전 버전의 Internet Explorer에서는 Microsoft.XMLHTTP를 사용해야 합니다. 우리는 두 가지 개체 유형(비 Microsoft 브라우저는 물론)을 모두 지원해야 합니다. 이전 코드를 기반으로 구축되고 Microsoft에 대한 지원을 추가하는 목록 4를 살펴보십시오.
Microsoft가 관련되어 있나요?
이 분야에 대한 Ajax와 Microsoft의 관심과 참여가 증가하고 있다는 사실에 대해 많은 글이 작성되었습니다. 실제로 2006년 하반기에 출시될 예정인 Microsoft의 최신 Internet Explorer 버전 7.0에서는 XMLHttpRequest를 직접 지원하기 시작하여 모든 Msxml2.XMLHTTP 생성 코드 대신 새 키워드를 사용할 수 있게 될 것이라고 합니다. 그러나 너무 흥분하지 마십시오. 오래된 브라우저는 여전히 지원되어야 하므로 크로스 브라우저 코드가 곧 사라지지는 않을 것입니다.
목록 4. Microsoft 브라우저에 대한 지원 추가
<스크립트 언어="자바스크립트" 유형="텍스트/자바스크립트">
var 요청 = 거짓;
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기(trymicrosoft) {
노력하다 {
request = new ActiveXObject("Msxml2.XMLHTTP");
} 잡기 (othermicrosoft) {
노력하다 {
요청 = new ActiveXObject("Microsoft.XMLHTTP");
} 잡기 (실패) {
요청 = 거짓;
}
}
}
if (!request)
Alert("XMLHttpRequest 초기화 오류!");
</script>
중괄호로 인해 혼동되기 쉽기 때문에 아래에서 각 단계를 소개합니다.
1. 새 변수 요청을 생성하고 false 값을 할당합니다. 판단 조건으로 false를 사용합니다. 이는 XMLHttpRequest 객체가 아직 생성되지 않았음을 의미합니다.
2. try/catch 블록을 추가합니다.
1) XMLHttpRequest 객체를 생성해보십시오.
2) 실패하는 경우(catch(trymicrosoft)):
1>최신 버전의 Microsoft 브라우저를 사용하여 Microsoft 호환 개체(Msxml2.XMLHTTP)를 생성해 보십시오.
2> 실패한 경우(catch(othermicrosoft)) 이전 버전의 Microsoft 브라우저를 사용하여 Microsoft 호환 개체(Microsoft.XMLHTTP)를 생성해 보십시오.
2) 실패(catch(실패))한 경우 요청 값이 여전히 거짓임을 보장합니다.
3. 요청이 여전히 거짓인지 확인합니다(모든 것이 잘 진행되면 거짓이 아닙니다).
4. 문제가 발생하면(요청이 false인 경우) JavaScript 경고를 사용하여 문제가 발생했음을 사용자에게 알립니다.
이런 방식으로 코드를 수정하고 Internet Explorer를 사용하여 테스트한 후에는 생성된 양식을 볼 수 있습니다(오류 메시지 없음). 내 실험 결과는 그림 2에 나와 있습니다.
그림 2. Internet Explorer가 정상적으로 작동하는 모습
정적 대 동적
목록 1, 3, 4를 다시 살펴보세요. 이 코드는 모두 스크립트 태그 내에 직접 중첩되어 있습니다. 메서드나 함수 본문에 배치되지 않은 이와 같은 JavaScript 코드를 정적 JavaScript라고 합니다. 이는 페이지가 사용자에게 표시되기 전에 코드가 실행된다는 의미입니다. (사양은 이 코드가 실행될 때 브라우저에 어떤 영향을 미칠지 완전히 정확하게 알지 못하더라도 사용자가 페이지와 상호 작용하기 전에 코드가 실행된다는 것을 보장합니다.) 이는 또한 가장 일반적인 방법이기도 합니다. Ajax 프로그래머는 XMLHttpRequest 객체를 생성합니다.
즉, 이 코드를 목록 5와 같은 메소드에 넣을 수도 있습니다.
목록 5. XMLHttpRequest 생성 코드를 메소드로 이동
<script 언어="javascript" type="text/javascript">
var 요청
함수 createRequest() {
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기(trymicrosoft) {
노력하다 {
request = new ActiveXObject("Msxml2.XMLHTTP");
} 잡기 (othermicrosoft) {
노력하다 {
요청 = new ActiveXObject("Microsoft.XMLHTTP");
} 잡기 (실패) {
요청 = 거짓;
}
}
}
if (!request)
Alert("XMLHttpRequest 초기화 오류!");
}
</script>
이런 방식으로 코드를 작성하는 경우 Ajax를 처리하기 전에 이 메서드를 호출해야 합니다. 따라서 Listing 6과 같은 코드도 필요합니다.
목록 6. XMLHttpRequest를 사용하여 메소드 생성
<script 언어="javascript" type="text/javascript">
var 요청
함수 createRequest() {
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기(trymicrosoft) {
노력하다 {
request = new ActiveXObject("Msxml2.XMLHTTP");
} 잡기 (othermicrosoft) {
노력하다 {
요청 = new ActiveXObject("Microsoft.XMLHTTP");
} 잡기 (실패) {
요청 = 거짓;
}
}
}
if (!request)
Alert("XMLHttpRequest 초기화 오류!");
}
함수 getCustomerInfo() {
생성요청();
// 요청 변수로 작업 수행
}
</script>
이 코드의 유일한 문제점은 오류 알림이 지연된다는 것입니다. 이것이 바로 대부분의 Ajax 프로그래머가 이 접근 방식을 사용하지 않는 이유입니다. 10개 또는 15개 필드, 선택 상자 등이 포함된 복잡한 양식이 있고 사용자가 14번째 필드(양식 순서에 따라 위에서 아래로)에 텍스트를 입력할 때 일부 Ajax 코드를 활성화하려고 한다고 가정합니다. 이 시점에서 getCustomerInfo()를 실행하면 XMLHttpRequest 객체를 생성하려고 시도하지만 (이 경우) 실패합니다. 그러면 사용자에게 앱을 사용할 수 없다는 경고가 명확하게 표시됩니다. 그러나 사용자는 이미 양식에 데이터를 입력하는 데 많은 시간을 소비하고 있습니다. 이는 매우 성가신 일이며, 성가신 행위로 인해 사용자가 귀하의 사이트를 다시 방문하도록 유도할 수는 없습니다.
정적 JavaScript를 사용하는 경우 사용자가 페이지를 클릭하면 오류 메시지가 매우 빠르게 표시됩니다. 그것도 짜증나는 일이군요, 그렇죠? 사용자는 웹 응용 프로그램이 자신의 브라우저에서 실행될 수 없다고 잘못 생각할 수 있습니다. 하지만 10분 동안 정보를 입력했는데 나중에 같은 오류가 표시되는 것보다는 훨씬 낫습니다. 따라서 사용자가 가능한 한 빨리 문제를 감지할 수 있도록 정적 코드를 작성하는 것이 좋습니다.
XMLHttpRequest로 요청을 보내고
요청 객체를 얻은 후 요청/응답 주기에 들어갈 수 있습니다. XMLHttpRequest의 유일한 목적은 요청을 보내고 응답을 받을 수 있도록 하는 것입니다. 그 밖의 모든 작업은 사용자 인터페이스 변경, 이미지 전환, 서버에서 반환된 데이터 해석 등 페이지의 JavaScript, CSS 또는 기타 코드 작업입니다. XMLHttpRequest를 준비한 후 서버에 요청을 보낼 수 있습니다.
Sandbox에 오신 것을 환영합니다.
Ajax는 샌드박스 보안 모델을 사용합니다. 따라서 Ajax 코드(특히 XMLHttpRequest 객체)는 해당 코드가 위치한 동일한 도메인에만 요청을 보낼 수 있습니다. 향후 기사에서 보안과 Ajax에 대해 더 자세히 다룰 예정이지만 지금은 로컬 시스템에서 실행되는 코드가 로컬 시스템의 서버측 스크립트에만 요청할 수 있다는 점만 알아 두십시오. Ajax 코드를 www.breakneckpizza.com 에서 실행하려면 www.breakneck.com 에서 실행되는 스크립트에서 요청을 보내야 합니다.
서버 URL을 설정하려면
먼저 연결된 서버의 URL을 결정해야 합니다. 이는 Ajax의 특별한 요구 사항은 아니지만 연결을 설정하는 데 여전히 필요하므로 이제 URL을 구성하는 방법을 분명히 알아야 합니다. 대부분의 애플리케이션에서 이 URL은 일부 정적 데이터와 사용자가 처리하는 양식의 데이터 조합으로 구성됩니다. 예를 들어 목록 7의 JavaScript 코드는 전화번호 필드의 값을 가져와 이를 사용하여 URL을 구성합니다.
목록 7. 요청 URL 생성하기
<스크립트 언어="자바스크립트" 유형="텍스트/자바스크립트">
var 요청 = 거짓;
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기(trymicrosoft) {
노력하다 {
request = new ActiveXObject("Msxml2.XMLHTTP");
} 잡기 (othermicrosoft) {
노력하다 {
요청 = new ActiveXObject("Microsoft.XMLHTTP");
} 잡기 (실패) {
요청 = 거짓;
}
}
}
if (!request)
Alert("XMLHttpRequest 초기화 중 오류가 발생했습니다!")
function getCustomerInfo() {
var 전화 = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
}
</script>
여기서 이해하기 어려운 것은 없습니다. 먼저 코드는 새 변수 Phone을 생성하고 ID가 "phone"인 양식 필드의 값을 할당합니다. Listing 8에서는 전화 필드와 해당 id 속성을 볼 수 있는 이 양식의 XHTML을 보여줍니다.
목록 8. Break Neck Pizza 양식
<body>
<p><img src="breakneck-logo_4c.gif" alt="브레이크 넥 피자" /></p>
<양식 작업="POST">
<p>전화번호 입력:
<input type="text" size="14" name="phone" id="phone"
onChange="getCustomerInfo();"
</p>
<p>주문하신 상품이 배송됩니다</p>
<div id="주소"></div>
<p>여기에 주문을 입력하세요:</p>
<p><textarea name="order"rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="피자 주문" id="submit" /></p>
</form>
</body>
또한 사용자가 전화번호를 입력하거나 전화번호를 변경할 때 목록 8에 표시된 getCustomerInfo() 메서드가 트리거된다는 점에 유의하세요. 이 메소드는 전화번호를 가져오고 url 변수에 저장된 URL 문자열을 구성합니다. Ajax 코드는 샌드박스 처리되어 동일한 도메인에만 연결할 수 있으므로 실제로 URL에 도메인 이름이 필요하지 않습니다. 이 예의 스크립트는 /cgi-local/lookupCustomer.php입니다. 마지막으로 전화번호는 GET 매개변수로 스크립트에 추가됩니다: "phone=" + escape(phone).
이전에 escape() 메서드를 본 적이 없다면 일반 텍스트로 올바르게 보낼 수 없는 문자를 이스케이프하는 데 사용됩니다. 예를 들어 전화번호의 공백은 %20 문자로 변환되어 해당 문자를 URL에 전달할 수 있습니다.
필요한 만큼 매개변수를 추가할 수 있습니다. 예를 들어 다른 매개변수를 추가해야 하는 경우 해당 매개변수를 URL에 추가하고 앰퍼샌드(&) 문자로 구분하면 됩니다. [첫 번째 매개변수는 물음표(?)로 스크립트 이름과 구분됩니다.]
요청 열기
연결할 URL이 있으면 요청을 구성할 수 있습니다. 이는 XMLHttpRequest 객체의 open() 메서드를 사용하여 수행할 수 있습니다. 이 메소드에는 5개의 매개변수가 있습니다.
request-type: 보낼 요청 유형입니다. 일반적인 값은 GET 또는 POST이지만 HEAD 요청도 보낼 수 있습니다.
url: 연결할 URL입니다.
asynch: 비동기 연결을 사용하려면 true이고, 그렇지 않으면 false입니다. 이 매개변수는 선택사항이며 기본값은 true입니다.
사용자 이름: 인증이 필요한 경우 여기에서 사용자 이름을 지정할 수 있습니다. 이 선택적 매개변수에는 기본값이 없습니다. 비밀번호: 인증이 필요한 경우 여기에서 비밀번호를 지정할 수 있습니다. 이 선택적 매개변수에는 기본값이 없습니다.
open()이 열리나요?
인터넷 개발자들은 open() 메소드가 정확히 무엇을 하는지에 대해 동의하지 않습니다. 그러나 실제로 요청을 열지는 않습니다. XHTML/Ajax 페이지와 해당 연결 스크립트 간의 네트워크 및 데이터 전송을 모니터링하는 경우 open() 메서드가 호출될 때 어떤 통신도 볼 수 없습니다. 이 이름을 선택한 이유는 확실하지 않지만 좋은 선택은 아닌 것 같습니다.
일반적으로 처음 세 개의 매개변수가 사용됩니다. 실제로 비동기 연결이 필요한 경우에도 세 번째 매개변수는 "true"로 지정해야 합니다. 이것이 기본값이지만 요청이 비동기식인지 동기식인지 명시적으로 지정하는 것이 이해하기 더 쉽습니다.
이들을 함께 결합하면 일반적으로 목록 9에 표시된 것과 같은 코드 줄이 생성됩니다.
목록 9. 열기 요청
함수 getCustomerInfo() {
var 전화 = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
}
일단 URL을 설정하고 나면 나머지는 쉽습니다. 대부분의 요청에는 GET(나중에 POST가 필요한 경우에 대해 설명)과 URL만 있으면 충분하며 이것이 open() 메서드를 사용하는 데 필요한 전부입니다.
비동기성에 대한 도전
이 시리즈의 다음 기사에서는 비동기 코드를 작성하고 사용하는 데 많은 시간을 할애할 것이지만 open()의 마지막 매개변수가 왜 그렇게 중요한지 이해해야 합니다. Web 1.0과 같은 일반적인 요청/응답 모델에서는 클라이언트(로컬 시스템에서 실행되는 브라우저 또는 코드)가 서버에 요청합니다. 요청은 동기적입니다. 즉, 클라이언트는 서버의 응답을 기다립니다. 클라이언트가 기다리고 있을 때 최소한 다음과 같은 형식으로 대기에 대한 알림을 받게 됩니다.
·모래시계(특히 Windows의 경우).
·회전하는 공(보통 Mac 컴퓨터에서).
·기본적으로 애플리케이션이 정지되고 잠시 후 커서가 변경됩니다.
이것이 바로 웹 애플리케이션이 투박하거나 느리게 느껴지는 이유입니다. 이는 진정한 상호작용성이 부족하기 때문입니다. 버튼을 누르면 방금 트리거된 요청이 응답될 때까지 애플리케이션을 효과적으로 사용할 수 없게 됩니다. 요청에 많은 서버 처리가 필요한 경우 대기 시간이 길어질 수 있습니다(적어도 이 다중 프로세서, 대기가 없는 DSL 세계에서는).
비동기식 요청은 서버의 응답을 기다리지 않습니다. 요청을 보낸 후에도 애플리케이션이 계속 실행됩니다. 사용자는 여전히 웹 양식에 데이터를 입력할 수 있고 양식에서 벗어날 수도 있습니다. 회전하는 공이나 모래시계가 없으며 앱이 눈에 띄게 정지되지 않습니다. 서버는 요청에 조용히 응답하고, 완료되면 원래 요청자에게 작업이 완료되었음을 알립니다(얼마나 빨리 알게 될 것입니다). 그 결과, 지연이나 느린 느낌이 덜하고 응답성이 뛰어나고 대화형이며 훨씬 더 빠른 느낌을 주는 앱이 탄생했습니다. 이는 Web 2.0의 한 부분일 뿐이지만 중요한 부분입니다. 모든 기존 GUI 구성 요소와 웹 디자인 패러다임은 느린 동기식 요청/응답 모델을 극복할 수 없습니다.
요청 보내기
open()으로 구성되면 요청을 보낼 수 있습니다. 다행스럽게도 요청을 보내는 메서드에는 open()보다 더 적절한 이름이 있습니다. 바로 send()입니다.
send()에는 전송할 내용인 매개변수가 하나만 있습니다. 하지만 이 방법을 고려하기 전에 이미 URL 자체를 통해 데이터를 보냈다는 점을 기억하세요.
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
데이터를 보내기 위해 send()를 사용할 수 있지만 , 그러나 URL 자체를 통해 데이터를 보내는 것도 가능합니다. 실제로 GET 요청(일반적인 Ajax 애플리케이션의 약 80%에서 발생)을 사용하면 URL을 사용하여 데이터를 보내는 것이 훨씬 쉽습니다. 보안 정보나 XML을 보내야 하는 경우 send()를 사용하여 콘텐츠를 보내는 것을 고려할 수 있습니다(보안 데이터 및 XML 메시지는 이 시리즈의 후속 기사에서 논의됩니다). send()를 통해 데이터를 전달할 필요가 없으면 이 메서드의 매개 변수로 null을 전달하면 됩니다. 따라서 이것이 이 기사의 예제에서 수행해야 할 전부임을 알게 될 것이다(목록 10 참조).
목록 10. 요청 보내기
함수 getCustomerInfo() {
var 전화 = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.send(null);
}
콜백 메소드 지정
현재 우리가 수행하는 작업에는 새롭거나 혁명적이거나 비동기적인 작업이 거의 없습니다. open() 메소드의 "true"라는 작은 키워드가 비동기 요청을 설정한다는 점을 인정해야 합니다. 하지만 그 외에 코드는 Java 서블릿과 JSP, PHP 또는 Perl을 사용한 프로그래밍과 다르지 않습니다. 그렇다면 Ajax와 Web 2.0의 가장 큰 비밀은 무엇일까요? 그 비밀은 XMLHttpRequest의 onreadystatechange 속성에 있습니다.
먼저 이 코드의 흐름을 이해해야 합니다. 필요한 경우 목록 10을 검토하세요. 요청을 작성한 다음 요청하십시오. 또한 요청이 비동기식이므로 JavaScript 메서드(예제에서는 getCustomerInfo())가 서버를 기다리지 않습니다. 따라서 코드는 계속 실행됩니다. 즉, 메서드가 종료되고 제어가 양식으로 반환됩니다. 사용자는 계속해서 정보를 입력할 수 있으며 애플리케이션은 서버를 기다리지 않습니다.
이는 흥미로운 질문을 제기합니다. 서버가 요청을 완료한 후에는 어떤 일이 발생합니까? 대답은 적어도 현재 코드에서는 아무 일도 일어나지 않는다는 것입니다! 분명히 이것은 작동하지 않으므로 서버는 XMLHttpRequest를 통해 전송된 요청 처리를 마친 후 수행할 작업에 대한 일종의 지침이 필요합니다.
JavaScript의 참조 함수:
JavaScript는 약한 유형의 언어이므로 변수를 사용하여 무엇이든 참조할 수 있습니다. 따라서 updatePage() 함수를 선언하면 JavaScript는 함수 이름도 변수로 처리합니다. 즉, 변수 이름 updatePage를 사용하여 코드에서 함수를 참조할 수 있습니다.
목록 11. 콜백 메소드 설정
function getCustomerInfo() {
var 전화 = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = 업데이트페이지;
request.send(null);
}
코드에서 이 속성이 설정되는 위치를 확인하는 것이 중요합니다. 이는 send()가 호출되기 전에 설정됩니다. 서버가 완료된 요청에 응답한 후 해당 속성을 볼 수 있도록 요청을 보내기 전에 이 속성을 설정해야 합니다. 이제 남은 것은 이 기사의 마지막 섹션의 초점인 updatePage() 메서드를 작성하는 것입니다.
처리 서버는
요청에 응답하고, 사용자는 (서버가 요청을 처리하는 동안) 웹 양식을 사용하고 있으며, 이제 서버는 요청 처리를 완료했습니다. 서버는 호출할 메소드를 결정하기 위해 onreadystatechange 속성을 확인합니다. 그렇지 않으면 비동기 여부에 관계없이 애플리케이션을 다른 애플리케이션처럼 취급하십시오. 즉, 서버에 응답하는 메서드를 작성하기 위해 반드시 특별한 조치를 취할 필요는 없으며, 양식을 변경하고 사용자가 다른 URL을 방문하도록 허용하거나 응답 서버에 필요한 모든 작업을 수행하기만 하면 됩니다. 이 섹션에서는 서버에 대한 응답과 일반적인 작업(사용자가 보는 양식의 일부를 즉시 변경)에 중점을 둡니다.
콜백과 Ajax
이제 서버가 완료되면 무엇을 해야 하는지 알려주는 방법을 살펴보았습니다. 즉, XMLHttpRequest 객체의 onreadystatechange 속성을 실행할 함수의 이름으로 설정합니다. 이런 방식으로 서버가 요청을 처리한 후 함수가 자동으로 호출됩니다. 또한 함수의 매개변수에 대해 걱정할 필요가 없습니다. 목록 12에 표시된 간단한 방법부터 시작합니다.
목록 12. 콜백 메소드에 대한 코드
<스크립트 언어="자바스크립트" 유형="텍스트/자바스크립트">
var 요청 = 거짓;
노력하다 {
요청 = 새로운 XMLHttpRequest();
} 잡기(trymicrosoft) {
노력하다 {
request = new ActiveXObject("Msxml2.XMLHTTP");
} 잡기 (othermicrosoft) {
노력하다 {
요청 = new ActiveXObject("Microsoft.XMLHTTP");
} 잡기 (실패) {
요청 = 거짓;
}
}
}
if (!request)
Alert("XMLHttpRequest 초기화 중 오류가 발생했습니다!")
function getCustomerInfo() {
var 전화 = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = 업데이트페이지;
request.send(null);
}
함수 업데이트페이지() {
Alert("서버가 완료되었습니다!");
}
</script>
서버가 작업을 완료했을 때 알려주는 몇 가지 간단한 경고를 발행할 뿐입니다. 자신의 웹 페이지에서 이 코드를 시험해 보고 브라우저에서 엽니다(이 예에서 XHTML을 보려면 목록 8 참조). 전화번호를 입력하고 필드를 나가면 팝업 경고 창이 표시되지만(그림 3 참조) 확인을 클릭하면 다시 나타납니다.
그림 3. 팝업 경고에 대한 Ajax 코드
브라우저에 따라 양식 팝업이 중지되기 전에 2개, 3개 또는 4개의 경고가 표시될 수도 있습니다. 무슨 일이야? 요청/응답 주기의 중요한 부분인 HTTP 준비 상태를 고려하지 않은 것으로 나타났습니다.
HTTP 준비 상태
앞서 언급했듯이 서버는 요청을 완료한 후 XMLHttpRequest의 onreadystatechange 속성에서 호출할 메서드를 찾습니다. 이는 사실이지만 불완전합니다. 실제로 HTTP 준비 상태가 변경될 때마다 이 메서드를 호출합니다. 이것은 무엇을 의미합니까? 먼저 HTTP 준비 상태를 이해해야 합니다.
HTTP 준비 상태는 요청의 상태 또는 조건을 나타냅니다. 요청이 시작되었는지, 응답을 받았는지 또는 요청/응답 모델이 완료되었는지 확인하는 데 사용됩니다. 또한 서버에서 제공하는 응답 텍스트나 데이터를 읽는 것이 안전한지 판단하는 데도 도움이 될 수 있습니다. Ajax 애플리케이션에는 알아야 할 다섯 가지 준비 상태가 있습니다.
·0: 요청이 발행되지 않았습니다(open()이 호출되기 전).
·1: 요청이 설정되었지만 아직 전송되지 않았습니다(send()가 호출되기 전).
·2: 요청이 전송되었으며 처리 중입니다(콘텐츠 헤더는 일반적으로 응답에서 얻을 수 있음).
·3: 요청이 처리되었으며 일반적으로 응답에서 일부 데이터를 사용할 수 있지만 서버가 응답을 완료하지 않았습니다.
·4: 응답이 완료되어 서버 응답에 접근하여 사용할 수 있습니다.
대부분의 브라우저 간 문제와 마찬가지로 이러한 준비 상태는 일관되게 사용되지 않습니다. 작업 준비 상태가 0에서 1, 2, 3, 4로 바뀔 것으로 예상할 수 있지만 그런 경우는 거의 없습니다. 일부 브라우저는 0이나 1을 보고하지 않고 2, 3, 4로 바로 시작합니다. 다른 브라우저는 모든 상태를 보고합니다. 다른 사람들은 준비 상태 1을 여러 번 보고합니다. 이전 섹션에서 볼 수 있듯이 서버는 updatePage()를 여러 번 호출하고 호출될 때마다 경고 상자가 나타납니다. 예상한 것과 다를 수 있습니다!
Ajax 프로그래밍의 경우 직접 처리해야 하는 유일한 상태는 준비 상태 4입니다. 이는 서버 응답이 완료되었고 응답 데이터를 사용하기에 안전함을 나타냅니다. 이를 기반으로 콜백 메소드의 첫 번째 행은 목록 13과 같아야 합니다.
목록 13. 준비 상태 확인
함수 updatePage() {
if (request.readyState == 4)
Alert("서버가 완료되었습니다!");
}
수정 후에는 서버의 처리가 완료되었음을 확인할 수 있습니다. 새 버전의 Ajax 코드를 실행해 보면 예상대로 경고 메시지가 한 번만 표시되는 것을 볼 수 있습니다.
HTTP 상태 코드
목록 13의 코드는 괜찮아 보이지만 문제가 있습니다. 서버가 요청에 응답하고 처리를 완료했지만 오류를 보고하면 어떻게 될까요? 서버 측 코드는 Ajax, JSP, 일반 HTML 양식 또는 기타 유형의 코드에 의해 호출된다는 점을 이해해야 하지만 기존 웹 관련 방법을 통해서만 정보를 보고할 수 있습니다. 웹 세계에서 HTTP 코드는 요청에서 발생할 수 있는 다양한 문제를 처리할 수 있습니다.
예를 들어, 잘못된 URL 요청을 입력하여 페이지가 존재하지 않는다는 의미인 404 오류 코드를 받은 상황이 발생했을 것입니다. 이는 HTTP 요청으로 수신될 수 있는 많은 오류 코드 중 하나일 뿐입니다(상태 코드의 전체 목록은 참고자료의 링크 참조). 접근 중인 데이터가 보호되거나 금지되어 있음을 나타내는 403, 401도 흔히 발생합니다. 두 경우 모두 이러한 오류 코드는 완료된 응답에서 가져옵니다. 즉, 서버가 요청을 이행했지만(즉, HTTP 준비 상태가 4임) 클라이언트가 기대한 데이터를 반환하지 않았습니다.
따라서 준비 상태 외에 HTTP 상태도 확인해야 합니다. 예상 상태 코드는 200입니다. 이는 모든 것이 잘 진행되었음을 의미합니다. 준비 상태가 4이고 상태 코드가 200이면 서버의 데이터를 처리할 수 있으며, 그 데이터는 (오류나 기타 문제가 있는 정보가 아닌) 요청한 데이터여야 합니다. 따라서 목록 14에 표시된 대로 콜백 메서드에 상태 확인도 추가해야 합니다.
목록 14. HTTP 상태 코드 확인
함수 updatePage() {
if (request.readyState == 4)
if (request.status == 200)
Alert("서버가 완료되었습니다!");
}
보다 강력한 오류 처리를 추가하고 상태 코드 검사를 한두 개 추가하여 과도한 복잡성을 피하려면 목록 15에서 수정된 updatePage() 버전을 살펴보세요.
목록 15. 간단한 오류 검사
함수 updatePage() {
추가
if (request.readyState == 4)
if (request.status == 200)
Alert("서버가 완료되었습니다!");
그렇지 않으면 (request.status == 404)
Alert("요청 URL이 존재하지 않습니다.");
또 다른
Alert("오류: 상태 코드는 " + request.status);
}
이제 getCustomerInfo()의 URL을 존재하지 않는 URL로 변경하고 어떤 일이 발생하는지 확인하세요. 요청한 URL이 존재하지 않는다는 경고 메시지가 표시됩니다. 좋습니다. 모든 오류 조건을 처리하기는 어렵지만이 작은 변경은 일반적인 웹 응용 프로그램의 문제의 80%를 다룰 수 있습니다.
응답 텍스트를 읽으면
이제 요청이 준비된 상태를 통해 처리되었는지 확인하고 서버는 정상 응답 (상태 코드를 통해)을 제공했으며 마지막으로 서버에서 반환 한 데이터를 처리 할 수 있습니다. 반환 된 데이터는 XMLHTTPREQUEST 객체의 responseText 속성에 저장됩니다.
형식 및 길이와 같은 ResponseText의 텍스트 내용은 의도적으로 모호합니다. 이렇게하면 서버가 텍스트를 무엇이든 설정할 수 있습니다. 예를 들어, 한 스크립트는 쉼표로 구분 된 값을 반환하고 다른 스크립트는 파이프 (| 문자)를 사용하여 값을 별도의 값으로 반환 할 수 있으며 다른 스크립트는 값을 별도의 값으로 반환합니다. 어디로 가야할지 결정하는 것은 서버에 달려 있습니다.
이 기사에 사용 된 예에서 서버는 파이프 문자로 분리 된 고객의 마지막 주문 및 고객 주소를 반환합니다. 그런 다음 순서와 주소는 양식에서 요소 값을 설정하는 데 사용됩니다.
Listing 16. 서버 응답
함수 처리 updatepage () {
if (request.readystate == 4) {
if (request.status == 200) {
var response = request.responsetext.split ( "|");
document.getElementById ( "Order"). value = response [0];
document.getElementById ( "주소"). innerHtml =
응답 [1] .replace (/ n/g, "");
} 또 다른
알림 ( "상태는" + request.status);
}
}
먼저 relateetext를 가져 와서 javaScript split () 메소드를 사용하여 파이프에서 분할하십시오. 결과 배열은 응답으로 배치됩니다. 배열의 첫 번째 값인 이전 순서는 응답 [0]으로 액세스하고 ID "Order"로 필드 값으로 설정됩니다. 고객 주소 인 두 번째 가치 응답 [1]은 조금 더 처리해야합니다. 주소의 선은 일반 라인 분리기 ( " n"문자)로 분리되므로 코드는 XHTML 스타일 라인 분리기 <br />를 사용해야합니다. 교체 프로세스는 replace () 함수 및 정규식을 사용하여 수행됩니다. 마지막으로, 수정 된 텍스트는 HTML 양식 div에서 내부 HTML로 사용됩니다. 결과적으로 그림 4와 같이 양식이 고객 정보로 갑자기 업데이트됩니다.
그림 4. 고객 데이터를 수신 한 후 목 양식
이 기사를 끝내기 전에 xmlhttprequest, responsexml의 또 다른 중요한 속성을 소개하고 싶습니다. 이 속성에는 서버가 XML 응답을 사용하기로 선택한 경우 XML 응답이 포함되어 있습니다. XML 응답 처리는 일반 텍스트 처리, 구문 분석, 문서 개체 모델 (DOM) 및 기타 문제와 매우 다릅니다. XML은 이후 기사에서 더 자세히 설명합니다. 그러나 responsexml은 일반적으로 responsetext와 함께 논의되므로 여기에 언급 할 가치가 있습니다. 많은 간단한 Ajax 응용 프로그램의 경우 ResponseText가 충분하지만 AJAX 응용 프로그램과 함께 XML도 잘 처리 할 수 있음을 곧 알 수 있습니다.
결론
당신은 xmlhttprequest에 약간 질려있을 수 있습니다. 그러나 Ajax를 사용하여 쓰는 모든 페이지와 응용 프로그램 에서이 객체를 반복해서 사용할 것입니다. 솔직히 XMLHTTPREQUEST에 대해 할 말이 있습니다. 다음 기사에서는 Post를 사용하고 요청을 요청하여 요청에서 컨텐츠 헤더를 설정하고 서버 응답에서 컨텐츠 헤더를 읽고 요청/응답 모델에서 요청을 인코딩하고 XML을 처리하는 방법을 이해합니다.
나중에 공통 AJAX 도구 상자를 소개합니다. 이 도구 상자는 실제로이 기사에 설명 된 많은 세부 사항을 숨겨 Ajax 프로그래밍을 더 쉽게 만들 수 있습니다. 도구 상자가 너무 많을 때 왜 저수준 세부 정보를 코딩 해야하는지 궁금 할 것입니다. 답은 응용 프로그램이 무엇을하는지 모르고 응용 프로그램에서 문제를 발견하기가 어렵다는 것입니다.
따라서 세부 사항을 무시하거나 단순히 찾아 보지 마십시오.이 편리하고 화려한 도구 상자에 문제가 발생하면 머리를 긁히거나 지원을 위해 이메일을 보내지 않아도됩니다. xmlhttprequest를 직접 사용하는 방법을 이해하면 가장 이상한 문제를 디버깅하고 해결하기가 쉽습니다. 도구 상자는 문제를 해결하는 경우에만 좋습니다.
따라서 xmlhttprequest에 익숙해 지십시오. 실제로 도구 상자를 사용하는 Ajax 코드가있는 경우 XMLHTTPREQUEST 객체와 그 속성 및 메소드를 사용하여 다시 작성해보십시오. 이것은 원칙을 더 잘 이해하는 데 도움이되는 좋은 운동입니다.
다음 기사는이 객체에 대해 더 논의하여 더 흥미로운 속성 (예 : Responsexml)과 게시물 요청을 사용하고 다른 형식으로 데이터를 보내는 방법을 탐색합니다. 코드 작성을 시작하면 한 달 안에 다시 논의하겠습니다.