๐Ÿ“ฒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ AJAX

13643 ๋‹จ์–ด ajaxJavaScriptJavaScript

๐Ÿค” AJAX๋ž€ ๋ฌด์—‡์ผ๊นŒ?

Ajax(Asynchronus JavaScript and XML)๋ž€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์—๊ฒŒ ๋น„๋™๊ธฐ ๋ฐฉ์‹์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์„œ๋ฒ„๊ฐ€ ์‘๋‹ตํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜์—ฌ ์›นํŽ˜์ด์ง€๋ฅผ ๋™์ ์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์„ ๋งํ•œ๋‹ค. Ajax๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” Web API์ธ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

Ajax ์ด์ „์˜ ์›นํŽ˜์ด์ง€๋Š” html ํƒœ๊ทธ๋กœ ์‹œ์ž‘ํ•ด์„œ html ํƒœ๊ทธ๋กœ ๋๋‚˜๋Š” ์™„์ „ํ•œ HTML์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „์†ก๋ฐ›์•„ ์›นํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋งํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ–ˆ๋‹ค. ํ™”๋ฉด์ด ์ „ํ™˜๋˜๋ฉด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด HTML์„ ์ „์†ก๋ฐ›์•„ ์›นํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋งํ–ˆ๋‹ค.

์ด๋Ÿฌํ•œ ์ „ํ†ต์ ์ธ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‹จ์ ์ด ์žˆ๋‹ค.

  1. ๋ณ€๊ฒฝ์‚ฌํ•ญ๊ณผ ์ƒ๊ด€์—†์ด ์–ธ์ œ๋‚˜ ์™„์ „ํ•œ HTML์„ ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์ „์†ก๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ํ†ต์‹  ๋ฐœ์ƒ.
  2. ๋ณ€๊ฒฝํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ๋ถ€๋ถ„๊นŒ์ง€ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ๋ Œ๋”๋ง โ†’ ์ˆœ๊ฐ„์ ์œผ๋กœ ๊นœ๋นก์ด๋Š” ํ˜„์ƒ ๋ฐœ์ƒ
  3. ํด๋ผ์ด์–ธํŠธ โ†โ†’ ์„œ๋ฒ„ ํ†ต์‹ ์ด ๋™๊ธฐ ๋ฐฉ์‹์ด๋ผ ๋ธ”๋กœํ‚น์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Œ.

๐Ÿท๏ธ 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 ์š”์ฒญ์„ ์ „์†กํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค.

  1. XMLHttpRequest.prototype.open ๋ฉ”์„œ๋“œ๋กœ HTTP ์š”์ฒญ์„ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.
  2. ํ•„์š”์— ๋”ฐ๋ผ XMLHttpRequest.prototype.setRequestHeader ๋ฉ”์„œ๋“œ๋กœ ํŠน์ • HTTP ์š”์ฒญ์˜ ํ—ค๋” ๊ฐ’์„ ์„ค์ •ํ•œ๋‹ค.
  3. ํ•„์š”์— ๋”ฐ๋ผ 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
      1. AJAX (816p~827p)

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ