
JavaScript: Ajax
- ์ฐธ๊ณ ํ ๊ธ
- Ajax๋?
- XMLHttpRequest์ ํ๋กํผํฐ
- XMLHttpRequest.open()
- XMLHttpRequest.setRequestHeader()
- XMLHttpRequest.send()
- XMLHttpRequest.abort()
- XMLHttpRequest.getAllResponseHeaders()
- XMLHttpRequest.getResponseHeader()
- XMLHttpRequest.timeout
- XMLHttpRequest.responseText
- XMLHttpRequest.responseXML
- XMLHttpRequest.status
- XMLHttpRequest.statusText
- XMLHttpRequest.readyState
- Attach callback function
์ฐธ๊ณ ํ ๊ธ
- https://xhr.spec.whatwg.org/
- http://www.w3schools.com/ajax/
- https://developer.mozilla.org/ko/docs/XMLHttpRequest
- https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
- http://huns.me/development/1291
Ajax๋?
Ajax๋ โAsynchronous JavaScript and XMLโ์ ์ฝ์๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ ๊ธฐ๋ฒ์ ํ๋๋ค. Ajax๋ ๋ ๋ฆฝ๋ ๊ธฐ์ ์ ์๋ฏธํ๊ธฐ๋ณด๋จ ์ฌ๋ฌ ๊ธฐ์ ์ ๋ฌถ์์ ์ง์นญํ๋ ์ฉ์ด์ ๊ฐ๊น๋ค. ์ค์ ๋ก Ajax๋ฅผ ๊ตฌํํ๋ ๋ฐ๋ HTML, CSS, DOM, ์๋ฐ์คํฌ๋ฆฝํธ, XML, XSLT, XPath, XMLHttpRequest ๋ฑ์ด ์ฌ์ฉ๋๋ค.
Ajax๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋จผ์ ๋ธ๋ผ์ฐ์ ์ ๋ด์ฅ ํจ์๋ก XMLHttpRequest ๊ฐ์ฒด(์์ธ์ง๋ง XMLHttpRequest๋ ๋ง์ดํฌ๋ก์ํํธ์์ ์ฒ์ ๋ง๋ค์๋ค)๋ฅผ ์์ฑํด์ผ ํ๋ค. ๊ณผ๊ฑฐ์ ActiveXObject๋ผ๋ ์๋ฆ ๋๋ ์ด๋ฆ์ ์์ฑ์๋ฅผ ์ฌ์ฉํ์ง๋ง, ์น ์ฌ์ฉ์์ ์ต์ ํ๊ฒฝ์ด IE8์ธ ์์ฆ์ ์ฌ์ฉํ์ง ์๋๋ค.
var xmlReq = false;
if (window.XMLHttpRequest) { // Non-Microsoft browsers
xmlReq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xmlReq = new ActiveXObject('Msxml2.XMLHTTP');
// XMLHttpRequest in later versions of Internet Explorer
} catch (e1) {
try {
xmlReq = new ActiveXObject('Microsoft.XMLHTTP');
// Try version supported by older versions of Internet Explorer
} catch (e2) {
// Unable to create an XMLHttpRequest with ActiveX
}
}
}
๋ง์๊ฐ ํญ์ฃผํ๋ 2000๋ ๋์๋ ์ฐ์ด๋ ์ฝ๋. ์ง๊ธ์ ๊ทธ๋ฅ ์๋ ํ ์ค๋ก ํด๊ฒฐ๋๋ค:
var xhr = new XMLHttpRequest();
์๋ ๋ ์์๋ฅผ ๊ฐ๊ฐ test1.html, test2.html๋ก ๋ง๋ค์ด์ ํ ์คํธ ํด๋ณด์:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test1.html</title>
<script>
function loadDoc() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
document.getElementById('demo').innerHTML = xhr.responseText;
}
};
xhr.open('GET', 'test2.html');
xhr.send();
}
</script>
</head>
<body>
<button onclick="loadDoc()">who r u</button>
<div id="demo">
</div>
</body>
</html>
<h2>i am waldo</h2>
XMLHttpRequest์ ํ๋กํผํฐ
XMLHttpRequest.open()
XMLHttpRequest.open( method, url [ , async ] )
- method: HTTP ๋ฉ์๋ ํ์ (get/post)
- url: ์๋ฒ ๊ฒฝ๋ก
- async: ๋น๋๊ธฐ ์ฌ๋ถ. (true/false)
request์ ์ ํ์ ์ง์ ํ๋ค. send()๋ก ๋ฉ์์ง๋ฅผ ๋ ๋ฆฌ๊ธฐ ์ , ์ด๋์ ์ด๋ค ๋ฐฉ์์ผ๋ก ์๋ํ๋์ง๋ฅผ ์ ํ๋ ๋ฉ์๋. method์ url์ ํ์์ง๋ง async๋ ๊ธฐ๋ณธ๊ฐ์ด true๋ก ์๋ตํ ์ ์๋ ํญ๋ชฉ์ด๋ค. async๋ฅผ false๋ก ์ง์ ํ ๊ฒฝ์ฐ send() ํ ์คํฌ๋ฆฝํธ์ ์งํ์ ์ค๋จํ๋ฉฐ ์๋ฒ๋ก๋ถํฐ ์๋ต์ด ์ฌ ๋๊น์ง ๋๊ธฐํ๋ค.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'test2.html');
// GET ๋ฐฉ์์ผ๋ก ์์ฒญํ URL ์ค์
XMLHttpRequest.setRequestHeader()
XMLHttpRequest.setRequestHeader( header, value )
- header: ํค๋์ ์ด๋ฆ
- value: ํค๋์ ๊ฐ
HttpRequest ํค๋์ ๊ฐ์ ์ค์ ํ๋ ๋ฉ์๋๋ก ๋ฐ๋์ open()๋ณด๋ค ๋์ค์ ํธ์ถ๋์ด์ผ ํ๋ค.
XMLHttpRequest.send()
XMLHttpRequest.send( [ string ] )
- string: ํผ ๋ฐ์ดํฐ๋ก ์ ์กํ ๋ฌธ์์ด
์๋ฒ๋ก request ์ก์ . open()์์ ์ค์ ํ ๊ฐ์ ๋ฐ๋ผ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ค. string์ HTTP ๋ฉ์๋ ํ์ ์ด POST์ผ ๊ฒฝ์ฐ์๋ง ๋ช ์ํ๋ฉฐ ํผ ๋ฐ์ดํฐ๋ก ๊ฐ์ฃผ๋๋ค. POST ๋ฐฉ์์ผ ๋ ์๋ ์์์ฒ๋ผ setRequestHeader()๋ก ์ปจํ ์ธ ํ์ ์ ์ง์ ํ์ง ์์ผ๋ฉด ์๋ฒ์์ ์ฒ๋ฆฌํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ string์ ๋ฐ๋์ ์ฟผ๋ฆฌ์คํธ๋ง ํํ๋ก ์์ฑ๋์ด์ผ ํ๋ค.
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test4.html');
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('first=111&second=222');
XMLHttpRequest.abort()
xhr.abort();
์ํ ์ค์ธ ํต์ ์ ์ค๋จํ๋ค. ์ด๋ฏธ ๋ ๋ผ๊ฐ request๋ ์ด์ฉ ์ ์๊ณ ๋จ์ง ์๋ต์ ๋ฌด์ํ ๋ฟ. ํต์
XMLHttpRequest.getAllResponseHeaders()
response ํค๋ ์ ๋ณด๋ฅผ ์ถ๋ ฅํ๋ค. send()๋ฅผ ์คํํ๊ธฐ ์ ์๋ ๋น ๊ฐ์ ๋ฆฌํดํ๋ค. ์ฆ, ์๋ฒ์ ์๋ต ํ์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ์๋
xhr.getAllResponseHeaders();
// "Server: Apache-Coyote/1.1
// Content-Type: text/html;charset=UTF-8
// Content-Length: 22
// Date: Wed, 27 Jan 2016 15:19:02 GMT
// "
XMLHttpRequest.getResponseHeader()
XMLHttpRequest.getResponseHeader( header )
- header: ํค๋์ ์ด๋ฆ
response ํค๋ ์ค ํน์ ํ ๊ฐ๋ง ๋ฆฌํดํ๋ค.
xhr.getResponseHeader('Content-Type')
// "text/html;charset=UTF-8"
XMLHttpRequest.timeout
์ง์ ํ ์๊ฐ์ ์ด๊ณผํ๋ฉด XMLHttpRequestEventTarget.ontimeout์ ํธ์ถํ๋ค. ๋จ์๋ ๋ฐ๋ฆฌ์ด(milliseconds)
XMLHttpRequest.responseText
์๋ฒ์ ์๋ต์ ๋ฌธ์์ด๋ก ๋ฆฌํด.
XMLHttpRequest.responseXML
์๋ฒ์ ์๋ต์ XMLDocument๋ก ํ์ฑํด ๋ฆฌํด. ํ์ฑ์ด ๋ถ๊ฐ๋ฅํ๋ฉด null์ ๋ฆฌํดํ๋ค.
XMLHttpRequest.status
์๋ต์ ์ํ์ฝ๋๋ฅผ ์ซ์๋ก ๋ฆฌํดํ๋ค.
XMLHttpRequest.statusText
์๋ต์ ์ํ์ฝ๋๋ฅผ ๋ฌธ์์ด๋ก ๋ฆฌํดํ๋ค. ๋จ์ํ ์ซ์๋ฅผ ๋ฌธ์์ด๋ก ํํํ๋๊ฒ ์๋๋ผ ์ํ์ฝ๋๊ฐ ๋ญ ์๋ฏธํ๋์ง ๋ํ๋ธ๋ค. ๊ฐ๋ น ์ํ์ฝ๋๊ฐ 404์ผ ๋ ๋ฆฌํด๋๋ ๊ฐ์ โNot Foundโ
XMLHttpRequest.readyState
XMLHttpRequest์ ํ์ฌ ์ํ๋ฅผ ์๋ฏธํ๋ค.
0
: request not initialized.1
: server connection established2
: request received3
: processing request4
: request finished and response is ready
Attach callback function
ํต์ ํ ์ฑ๊ณต ํน์ ์คํจ์ ๋ฐ๋ฅธ ์ฒ๋ฆฌ๊ฐ ํ์ํ๋ค๋ฉด ์๋ฒ๊ฐ ์๋ตํ์ ๋ ์ฝ๋ฐฑ์ผ๋ก ํธ์ถ๋๋ ํ๋กํผํฐ์ ํจ์๋ฅผ ํ ๋นํ๋ฉด ๋๋ค. ์ฝ๋ฐฑ ํจ์๋ฅผ ํ ๋นํ๋ ๋ฐฉ๋ฒ์ XMLHttpRequest์ onreadystatechange() ๋ฉ์๋๋ฅผ ์ด์ฉํ๊ฑฐ๋ XMLHttpRequestEventTarget์ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ, ๊ทธ๋ฆฌ๊ณ EventTarget.addEventListener() ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด ์๋ค.
XMLHttpRequest.onreadystatechange
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log('complete');
}
};
xhr.open('GET', 'http://somewhere');
xhr.send();
onreadystatechange()๋ XMLHttpRequest์ ํ๋กํผํฐ๋ก ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ์ฅํ๋ค. ์ด ๋ฉ์๋๋ readyState์ ๊ฐ์ด ๋ณํ ๋๋ง๋ค ํธ์ถ๋๋ ๊ทธ๋๋ก ์คํ๋๋๋ก ํ๋ฉด ์ ๋๊ณ readyState์ ๊ฐ์ ์ฒดํฌํ๋ ์กฐ๊ฑด ๋ถ๊ธฐ๋ฅผ ์ถ๊ฐํด์ผ ์ํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
EventTarget.addEventListener()
EventTarget.addEventListener( eventType, callback )
- eventType: callback์ด ์คํ๋ ์ด๋ฒคํธ์ ์ ํ (ex: โloadโ)
- callback: eventType์ ์ง์ ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ์ ๋ ์คํํ ํจ์
addEventListener()๋ IE8์์ ์ง์๋์ง ์์ผ๋ ์ฃผ์ํ ๊ฒ. ์
์ ์ถ
function reqListener () {
console.log(this.responseText); // this == xhr
}
var xhr = new XMLHttpRequest();
xhr.addEventListener('load', reqListener);
xhr.open('GET', 'http://example.org/example.txt');
xhr.send();
XMLHttpRequestEventTarget
var xhr = new XMLHttpRequest();
console.debug(xhr);
xhr.onabort = function() {
console.log('onabort - xhr.readyState: ' + xhr.readyState);
};
xhr.onerror = function() {
console.log('onerror - xhr.readyState: ' + xhr.readyState);
console.log('xhr.status: ' + xhr.status);
};
xhr.onloadstart = function() {
console.log('onloadstart - xhr.readyState: ' + xhr.readyState);
};
xhr.onloadend = function() {
console.log('onloadend - xhr.readyState: ' + xhr.readyState);
};
xhr.onprogress = function(event) {
console.log('progress - xhr.readyState: ' + xhr.readyState);
console.log('loaded: ' + event.loaded);
console.log('size: ' + event.size);
};
xhr.onload = function() {
console.log('complete');
};
xhr.open('GET', 'test2.html');
xhr.send();
XMLHttpRequestEventTarget์ XMLHttpRequest์ ์ํผํด๋์ค๋ค. ์์๋ฐ๋ ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค:
onabort
: abort ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํธ์ถ๋๋ค.onerror
: ์๋ฒ์ ์๋ต์ด 200์ด ์๋ ๋ ํธ์ถ๋๋ค.onloadstart
: XHR ์์ฒญ์ ์์ํ ๋ ํธ์ถ๋๋ค.onloadend
: XHR ์์ฒญ์ด ์๋ฃ๋๋ฉด ํธ์ถ๋๋ค. onload()์ ๋ค๋ฅด๊ฒ ์ฑ๊ณต/์คํจ ์๊ด์์ด ํธ์ถ๋๋ค.onprogress
: onloadstart()์ onloadend() ์ฌ์ด์ ํธ์ถ๋๋ค. ํ๋ผ๋ฏธํฐ๋ก ProgressEvent๋ฅผ ์ ๋ฌ๋ฐ์ผ๋ฉฐ ์ด ๊ฐ์ฒด์ ํ๋กํผํฐ๋ ๋ธ๋ผ์ฐ์ ๋ง๋ค ๋ค๋ฅผ ์ ์๋ค.onload
: XHR ์์ฒญ์ด โ์ฑ๊ณต์ ์ผ๋กโ ์๋ฃ๋๋ฉด ํธ์ถ๋๋ค. ์ฆ XHR.status๊ฐ 200์ผ ๋๋ง ํธ์ถ๋๋ ๋ฉ์๋.ontimeout
: XHR.timeout์ผ๋ก ์ค์ ํ ์๊ฐ ๋ด์ ์๋ต์ด ๋์ฐฉํ์ง ์์ผ๋ฉด ํธ์ถ๋๋ค. ์์ฒญ์ ์คํจํ ๊ฒ์ผ๋ก ๊ฐ์ฃผ๋๋ฉฐ onprogress()์ onload()๋ ํธ์ถ๋์ง ์๋๋ค.