๐ฒ ์๋ฐ์คํฌ๋ฆฝํธ์ AJAX
๐ค AJAX๋ ๋ฌด์์ผ๊น?
Ajax(Asynchronus JavaScript and XML)๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ์๊ฒ ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ์๋ฒ๊ฐ ์๋ตํ ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ฌ ์นํ์ด์ง๋ฅผ ๋์ ์ผ๋ก ๊ฐฑ์ ํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ๋งํ๋ค. Ajax๋ ๋ธ๋ผ์ฐ์ ์์ ์ ๊ณตํ๋ Web API์ธ XMLHttpRequest
๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ๋ค.
Ajax ์ด์ ์ ์นํ์ด์ง๋ html ํ๊ทธ๋ก ์์ํด์ html ํ๊ทธ๋ก ๋๋๋ ์์ ํ HTML์ ์๋ฒ๋ก๋ถํฐ ์ ์ก๋ฐ์ ์นํ์ด์ง ์ ์ฒด๋ฅผ ์ฒ์๋ถํฐ ๋ค์ ๋ ๋๋งํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค. ํ๋ฉด์ด ์ ํ๋๋ฉด ์๋ฒ๋ก๋ถํฐ ์๋ก์ด HTML์ ์ ์ก๋ฐ์ ์นํ์ด์ง ์ ์ฒด๋ฅผ ์ฒ์๋ถํฐ ๋ค์ ๋ ๋๋งํ๋ค.
์ด๋ฌํ ์ ํต์ ์ธ ๋ฐฉ์์ ๋ค์๊ณผ ๊ฐ์ ๋จ์ ์ด ์๋ค.
- ๋ณ๊ฒฝ์ฌํญ๊ณผ ์๊ด์์ด ์ธ์ ๋ ์์ ํ HTML์ ์๋ฒ๋ก๋ถํฐ ์ ์ก๋ฐ๊ธฐ ๋๋ฌธ์ ๋ถํ์ํ ๋ฐ์ดํฐ ํต์ ๋ฐ์.
- ๋ณ๊ฒฝํ ํ์๊ฐ ์๋ ๋ถ๋ถ๊น์ง ์ฒ์๋ถํฐ ๋ค์ ๋ ๋๋ง โ ์๊ฐ์ ์ผ๋ก ๊น๋นก์ด๋ ํ์ ๋ฐ์
- ํด๋ผ์ด์ธํธ โโ ์๋ฒ ํต์ ์ด ๋๊ธฐ ๋ฐฉ์์ด๋ผ ๋ธ๋กํน์ด ๋ฐ์ํ ์ ์์.
๐ท๏ธ JSON
JSON(JavaScript Object Notation)์ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ HTTP ํต์ ์ ์ํ ํ ์คํธ ๋ฐ์ดํฐ ํฌ๋งท์ด๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์ ์ข ์๋์ง ์๋ ์ธ์ด ๋ ๋ฆฝํ ๋ฐ์ดํฐ ํฌ๋งท์ผ๋ก, ๋๋ถ๋ถ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์์ ์ฌ์ฉํ ์ ์๋ค. JSON์ ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด๊ณผ ์ ์ฌํ๊ฒ ํค์ ๊ฐ์ผ๋ก ๊ตฌ์ฑ๋ ์์ํ ํ ์คํธ๋ค.
JSON.stringify
ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก ๊ฐ์ฒด๋ฅผ ์ ์กํ๋ ค๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฌธ์์ดํํด์ผ ํ๋๋ฐ ์ด๋ฅผ ์ง๋ ฌํ(serializing)์ด๋ผํ๋ค. JSON.stringify ๋ฉ์๋๋ ๊ฐ์ด๋ ๊ฐ์ฒด๋ฅผ JSON ํฌ๋งท์ ๋ฌธ์์ด๋ก ๋ณํํ๋ค.
console.log(JSON.stringify({ x: 5, y: 6 }));
// expected output: "{"x":5,"y":6}"
console.log(JSON.stringify([new Number(3), new String('false'), new Boolean(false)]));
// expected output: "[3,"false",false]"
console.log(JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }));
// expected output: "{"x":[10,null,null,null]}"
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// expected output: ""2006-01-02T15:04:05.000Z""
JSON.parse
์๋ฒ๋ก๋ถํฐ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก๋ JSON ๋ฐ์ดํฐ๋ ๋ฌธ์์ด์ด๋ค. ์ด ๋ฌธ์์ด์ ๊ฐ์ฒด๋ก์ ์ฌ์ฉํ๋ ค๋ฉด JSON ํฌ๋งท์ ๊ฐ์ฒดํํด์ผ ํ๋๋ฐ ์ด๋ฅผ ์ญ์ง๋ ฌํ(deserializing)๋ผ ํ๋ค. JSON.parse ๋ฉ์๋๋ JSON ํฌ๋งท์ ๋ฌธ์์ด์ ๊ฐ์ฒด๋ก ๋ณํํ๋ค.
const json = '{"result":true, "count":42}';
const obj = JSON.parse(json);
console.log(obj.count);
// expected output: 42
console.log(obj.result);
// expected output: true
๐ฒ XMLHttpRequest
๋ธ๋ผ์ฐ์ ๋ ์ฃผ์์ฐฝ์ด๋ HTML์ form
ํ๊ทธ ๋๋ a
ํ๊ทธ๋ฅผ ํตํด HTTP ์์ฒญ ์ ์ก ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ ์ ๊ณตํ๋ค. ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ HTTP ์์ฒญ์ ์ ์กํ๋ ค๋ฉด XMLHttpRequest
๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ค.
XMLHttpRequest ๊ฐ์ฒด ์์ฑ
XMLHttpRequest
๊ฐ์ฒด๋ XMLHttpRequest
์์ฑ์ ํจ์๋ฅผ ํธ์ถํ์ฌ ์์ฑํ๋ค. XMLHttpRequest
๊ฐ์ฒด๋ ๋ธ๋ผ์ฐ์ ์์ ์ ๊ณตํ๋ Web API์ด๋ฏ๋ก ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์๋ง ์ ์์ ์ผ๋ก ์คํ๋๋ค.
const xhr = new XMLHttpRequest();
HTTP ์์ฒญ ์ ์ก
HTTP ์์ฒญ์ ์ ์กํ๋ ๊ฒฝ์ฐ ๋ค์ ์์๋ฅผ ๋ฐ๋ฅธ๋ค.
XMLHttpRequest.prototype.open
๋ฉ์๋๋ก HTTP ์์ฒญ์ ์ด๊ธฐํํ๋ค.- ํ์์ ๋ฐ๋ผ
XMLHttpRequest.prototype.setRequestHeader
๋ฉ์๋๋ก ํน์ HTTP ์์ฒญ์ ํค๋ ๊ฐ์ ์ค์ ํ๋ค. - ํ์์ ๋ฐ๋ผ
XMLHttpRequest.prototype.send
๋ฉ์๋๋ก HTTP ์์ฒญ์ ์ ์กํ๋ค.
// XMLHttpRequest ๊ฐ์ฒด ์์ฑ
const xhr = new XMLHttpRequest();
// HTTP ์์ฒญ ์ด๊ธฐํ
xhr.open('GET', '/user');
// HTTP ์์ฒญ ํค๋ ์ค์
// ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ๋ก ์ ์กํ ๋ฐ์ดํฐ์ MIME ํ์
์ง์ :: json
xhr.setRequestHeader('content-type', 'application/json');
HTTP ์๋ต ์ฒ๋ฆฌ
์๋ฒ๊ฐ ์ ์กํ ์๋ต์ ์ฒ๋ฆฌํ๋ ค๋ฉด XMLHttpRequest
๊ฐ์ฒด๊ฐ ๋ฐ์์ํค๋ ์ด๋ฒคํธ๋ฅผ ์บ์นํด์ผํ๋ค. XMLHttpRequest
๊ฐ์ฒด๊ฐ ๊ฐ๋ ์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ ์ค์์ HTTP ์์ฒญ์ ํ์ฌ ์ํ๋ฅผ ๋ํ๋ด๋ readyState
ํ๋กํผํฐ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๊ฒฝ์ฐ ๋ฐ์ํ๋ readystatechangae
์ด๋ฒคํธ๋ฅผ ์บ์นํ์ฌ ๋ค์๊ณผ ๊ฐ์ด HTTP ์๋ต์ ์ฒ๋ฆฌํ ์ ์๋ค.
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1')';
xhr.send();
// readystatechange ์ด๋ฒคํธ๋ HTTP ์์ฒญ์ ํ์ฌ ์ํ๋ฅผ ๋ํ๋ด๋ readyState ํ๋กํผํฐ๊ฐ
// ๋ณ๊ฒฝ๋ ๋๋ง๋ค ๋ฐ์ํ๋ค.
xhr.onreadystatechange = () => {
// readyState ํ๋กํผํฐ๋ HTTP ์์ฒญ์ ํ์ฌ ์ํ๋ฅผ ๋ํ๋ธ๋ค.
// readyState ํ๋กํผํฐ ๊ฐ์ด 4(XMLHttpRequest.DONE)๊ฐ ์๋๋ฉด
// ์๋ฒ ์๋ต์ด ์๋ฃ๋์ง ์์ ์ํ์ด๋ค.
if (xhr.readyState !== XMLHttpRequest.DONE) {
return;
}
if (xhr.status === 200) {
console.log(JSON.parse(xhr.response));
}
else {
console.error('Error', xhr.status, xhr.statusText));
}
}
send ๋ฉ์๋๋ฅผ ํตํด HTTP ์์ฒญ์ ์๋ฒ์ ์ ์กํ๋ฉด ์๋ฒ๋ ์๋ต์ ๋ฐํํ๋ค. ํ์ง๋ง ์ธ์ ์๋ต์ด ํด๋ผ์ด์ธํธ์ ๋๋ฌํ ์ง ์ ์ ์๊ธฐ ๋๋ฌธ์ readystatechange
๊ฐ์ ์ด๋ฒคํธ๋ฅผ ํตํด HTTP ์์ฒญ์ ํ์ฌ ์ํ๋ฅผ ํ์ธํด์ผํ๋ค.
onreadystatechange
์ด๋ฒคํธ ํธ๋ค๋ฌ ํ๋กํผํฐ์ ํ ๋นํ ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ HTTP ์์ฒญ์ ํ์ฌ ์ํ๋ฅผ ๋ํ๋ด๋ xhr.readyState
๊ฐ XMLHttpRequest.DONE
์ธ์ง ํ์ธํ์ฌ ์๋ฒ์ ์๋ต์ด ์๋ฃ๋์๋์ง ํ์ธํ๋ค. ์ดํ ์๋ฒ์ ์๋ต์ด ์๋ฃ๋๋ฉด HTTP ์์ฒญ์ ๋ํ ์๋ต ์ํ(HTTP ์ํ ์ฝ๋)๋ฅผ ๋ํ๋ด๋ xhr.status๊ฐ 200์ธ์ง ํ์ธํ์ฌ ์ ์ ์ฒ๋ฆฌ์ ์๋ฌ ์ฒ๋ฆฌ๋ฅผ ๊ตฌ๋ถํ๋ค.
๐ง ์ ๋ฆฌ
- AJAX๋, ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ฒ์๊ฒ ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๊ณ ์๋ฒ๊ฐ ์๋ตํ ๋ฐ์ดํฐ๋ฅผ ์์ ํ์ฌ ์นํ์ด์ง๋ฅผ ๋์ ์ผ๋ก ๊ฐฑ์ ํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ๋งํ๋ค.
- JSON์ ํด๋ผ์ด์ธํธ์ ์๋ฒ ๊ฐ์ HTTP ํต์ ์ ์ํ ํ ์คํธ ๋ฐ์ดํฐ ํฌ๋งท์ด๋ค.
- XMLHttpRequest ๊ฐ์ฒด๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํ์ฌ HTTP ์์ฒญ์ ์ ์กํ๊ธฐ ์ํด ์ฌ์ฉํ๋ค.
๐ ์ฐธ๊ณ ์๋ฃ
- ๋ชจ๋ ์๋ฐ์คํฌ๋ฆฝํธ Deep Dive
- AJAX (816p~827p)
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฒ ์๋ฐ์คํฌ๋ฆฝํธ์ AJAX), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@thumb_hyeok/์๋ฐ์คํฌ๋ฆฝํธ์-AJAX์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค