본문 바로가기

환영합니다. 이 블로그 번째 방문자입니다.
CS Knowledge

XMLHttpRequest

나는 "자바스크립트 완벽 가이드 6판"을 참고하여 공부했는데, 새롭게 나온 "JavaScript: The Definitive Guide, 7th Edition"  원본에는 이렇게 써있다. 

 

GOODBYE XMLHTTPREQUEST
The fetch() API replaces the baroque and misleadingly named XMLHttpRequest API (which has nothing to do with XML).

 

사실 나도 fetch() 쓴다. 그렇지만 XMLHttpRequest를 이해하면 HTTP 스크립팅 이해에 도움이 될 것 같아서 공부하려고 한다.


HTTP(HyperText Transfer Protocol) : 웹 브라우저가 서버로부터 문서를 전송받거나 폼의 내용을 보내는 방법, 그리고 해당 요청의 내용에 대해 서버가 응답하는 방법을 정의

 

♦️ Ajax란

Ajax : HTTP를 조작하는데 특화된 웹 애플리케이션 설계 방식을 가리키는 용어
 
Ajax는 Asynchronous Javascript and XML, 비동기 자바스크립트와 XML의 약어이다.
Ajax의 핵심은 HTTP를 조작하여, 페이지를 다시 불러오지 않고도 웹 서버와 데이터를 교환할 수 있도록 하는 것이다. 

 

 

♦️ Comet이란

Comet : HTTP를 조작하는 웹 애플리케이션 설계와 관련된 용어
Comet은 비동기적으로 메시지를 클라이언트로 보내는 방식의 통신을 가능하게 하는 웹 서버로, Ajax와 반대개념이라고 할 수 있다.

 

 

♦️ Ajax와 Comet

웹 애플리케이션이 서버로부터 전달받은 메시지에 응답해야 한다고 해보자.

 

이 때, Ajax는 클라이언트가 서버의 데이터를 '끌어'온다.

Comet은 서버에서 클라이언트로 데이터를 '밀어'넣는다.

 

다만, 둘의 치명적인 공통점은 둘 다 미국의 광택제 상표명이라는 것이다.

Comet의 전송 메커니즘이 Ajax보다 복잡하기 때문에 안정적으로 구현하기는 어협다. 

 

 

 

♦️ Ajax 전송 방법

 

⓵ <iframe> 태그 사용

<img> 태그는 클라이언트에서 서버로 데이터를 보내지만, 서버의 응답은 항상 이미지 형태이기 때문에 클라이언트가 정확한 정보를 알기 어렵다. 이 보다는 <iframe> 태그가 많은 일을 할 수 있다. 

 

💎 <img> 태그의 src 프로퍼티

더보기

[Javascript] <img> 태그의 src 프로퍼티에 URL을 설정

-> 해당 URL로부터 이미지를 내려받기 위해 HTTP GET 요청이 준비

-> [Javascript] 쿼리스트링을 암호화한 이미지의 URL을 웹 서버에 전달하고 <img> 태그의 src 프로퍼티로 설정

  

⓶ <script> 태그의 src 프로퍼티를 활용

자바스크립트 인터프리터가 데이터를 자동으로 해석할 수 있도록, 서버의 응답 데이터를 JSON 형태로 인코딩한다. 

 

 

⓷ XMLHttpRequest API 사용

 이것이 바로 주제!

 

 

 

 ♦️ XMLHttpRequest 사용하기

 

var request = new XMLHttpRequest();

 

HTTP 요청과 서버로부터 받은 응답은 다음과 같이 구성되어 있다.

 

HTTP 요청 서버로부터 받은 HTTP 응답
1. HTTP 요청 방법 또는 동사
2. 요청된 URL
3. 인증 정보를 포함하는 부속 요청 헤더
4. (선택 사항) 요청 본문 
1. 요청의 성공과 실패를 구분할 수 있는 숫자와 문자 상태 코드
2. 응답 헤더의 집합
3. 응답 본문

 

 

♦️ 요청 설정하기

요청은 아래의 순서에 따라 호출해야 한다.

 

⑴  HTTP 요청 방법 또는 동사

 

request.open("GET", "data.csv");
// HTTP Get 요청으로 "data.csv" 의 내용을 가져오도록 한다.

 

open() 메소드의 첫 번째 인자는 HTTP 요청 방식 또는 동사다. 보편적으로 지원되는 것은 GET & POST 요청이다. 하지만 DELETE, HEAD, OPTIONS, PUT 도 사용할 수는 있다. 

 

 

⑵ 요청된 URL

open() 의 두 번째 인자는 요청할 목적 URL이다. 

 

 

⑶ 요청 헤더 설정하기

만약, POST 요청을 보낼 때 본문의 MIME 타입으로 "Content-Type" 헤더를 지정할 필요가 있다면, 다음과 같이 설정한다.

 

request.setRequestHeader("Content-Type","text/plain");

 

 

⑷ 부가적인 요청 본문을 지정하고 서버로 전송하는 것

 

request.send(null);

 

GET 요청은 본문을 가질 수 없으므로 send() 메서드의 인자를 null 또는 생략해야 한다. 

POST 요청은 본문을 포함하며, 해당 본문은 setRequestHeader()에서 지정한 Content-Type 형식이어야 한다.

 

💎 POST 방식으로 텍스트 문자열을 전송하고 서버의 응답은 무시하기

더보기
function postMessage(msg){
	var request = new XMLHttpRequest();
    request.open("POST", "/log.php");
    request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
    request.send(msg);
}

 

 

♦️ 응답 데이터 가져오기

status와 statusText 프로퍼티는 HTTP의 상태를 숫자+문자 형태로 반환한다.

응답 데이터는 우리가 항상 보고 싶어하는 200  OK (성공)이나 꼴도 보기 싫은 404 Not Found (못 찾음)을 얘기한다. 

 

응답이 준비되었음을 통보 받기 위해서는 XMLHttpRequest의 readystatechange 이벤트를 사용하면 된다. 

이 이벤트 타입에는 readyState 프로퍼티가 존재하는데 이는 HTTP 요청 상태를 나타내는 정수 값이다. 

 

상수 의미
UNSENT 0 open() 메서드가 아직 호출되지 않음
OPENED 1 open() 메서드가 호출됨
HEADERS_RECEIVED 2 HTTP 헤더를 전송받음
LOADING 3 응답 본문을 전송받는 중임
DONE 4 응답이 완료됨

 

보통 보고 싶어하는 것이 4일 것이다. 브라우저의 readyState가 4로 변경되거나 서버의 응답이 완료되면 readystatechange를 발생시킨다. 이 이벤트를 사용하기 위해서는 XMLHttpRequest 객체의 onreadystatechange 프로퍼티를 이벤트 핸들러 함수로 설정해야 한다. 

 

function getText(url, callback){
	var request = new XMLHttpRequest();
    request.open("GET", url);
    request.onreadystatechange = function(){
    	if(request.readyState === 4 && request.status === 200){
        	var type = request.getResponseHeader("Content-Type");
            if(type.match(/^text/) callback(request.responseText);
        }
    };
    request.send(null);
}

 

 

♦️ 응답 해석하기

서버가 객체나 배열과 같이 구조적인 데이터를 응답으로 보내게 하려면, 해당 데이터를 JSON 형식으로 구성한 문자열로 만들 수 있어야 한다.  JSON 형식의 문자열을 받으면, responseText를 JSON.parse()에 전달하면 된다.

 

function get(url, callback) {
	var request = new XMLHttpRequest();
	request.open("GET", url);
	request.onreadystatechange = function () {
		if (request.readyState === 4 && request.status === 200) {
			var type = request.getResponseHeader("Content-Type");
            
			if (type.indexOf("xml") !== -1 && request.responseXML)// 문서 형식일 때
				callback(request.responseXML);
			else if (type === "application/json") // JSON 형식일 때
				callback(JSON.parse(request.responseText));
			else callback(request.responseText); // 문자열 형식일 때
		}
	};
}

 

 

♦️ 요청 본문 인코딩 [JSON 인코딩 요청]

JSON 형식으로 인코딩된 데이터를 본문으로 보내는 HTTP POST 요청 만들기

 

function postJSON(url, data, callback) {
	var request = new XMLHttpRequest();
	request.open("POST", url);
	request.onreadystatechange = function () {
		if (request.readyState === 4 && callback) {
			callback(request);
		}
		request.setRequestHeader("Content-Type", "application/json");
		request.send(JSON.stringify(data));
	};
}

 

 

♦️ HTTP 요청이 실패로 완료되는 상황

아래의 3개 중 무조건 하나만 발생시킨다.

 

⓵ 요청 시간 초과 : timeout 이벤트 발생

⓶ 요청 취소 : abort 이벤트 발생

⓷ 기타 네트워크 오류 : error 발생

 

끝!

'CS Knowledge' 카테고리의 다른 글

DOM & BOM  (0) 2022.04.19
Prototype, 프로토타입  (0) 2022.04.14
Semantic Markup, 시맨틱 마크업  (0) 2022.04.06