๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ

AJAX๋ž€?

  1. JavaScript๋ฅผ ์ด์šฉํ•œ ๋น„๋™๊ธฐ ํ†ต์‹ 
  2. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๊ฐ„์— XML, JSON ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๊ธฐ์ˆ ์ด๋‹ค.
  3. AJAX๋Š” ๊ธฐ์ˆ  ์ž์ฒด๋ฅผ ๋œปํ•˜๊ธฐ ๋ณด๋‹จ, HTML, XHTML, CSS, JavaScript, DOM, XML, XSLT, XMLHttpRequest ์˜ค๋ธŒ์ ํŠธ๋“ค์ด ์กฐํ•ฉํ•œ ๊ธฐ์ˆ ์˜ ์ด์นญ์„ ์ผ์ปซ๋Š”๋‹ค.
  4. XMLHttpRequest ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ, ํŽ˜์ด์ง€ ์ƒˆ๋กœ๊ณ ์นจ ์—†์ด ํŽ˜์ด์ง€์˜ ์ผ๋ถ€๋งŒ์„ ์œ„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•˜๋Š” ๊ธฐ๋ฒ•์ด๋‹ค.
  5. AJAX(Asynchronous JavaScript and XML)์˜ X๋Š” XML์„ ๋œปํ•˜์ง€๋งŒ, JSON์ด ๋” ๊ฐ€๋ณ๊ณ , ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์˜ค๋ธŒ์ ํŠธ๋กœ ์‰ฝ๊ฒŒ ๋ณ€ํ™˜๋œ๋‹ค๋Š” ์  ๋•Œ๋ฌธ์— XML ๋ณด๋‹ค ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.

 

AJAX๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

  • ํ™”๋ฉด์—์„œ ๋ฌด์–ธ๊ฐ€ ๋ถ€๋ฅด๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ, ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค.
  • HTTP ํ”„๋กœํ† ์ฝœ์€ ํด๋ผ์ด์–ธํŠธ์ชฝ์—์„œ Request๋ฅผ ๋ณด๋‚ด๊ณ  ์„œ๋ฒ„์ชฝ์—์„œ Response๋ฅผ ๋ฐ›์œผ๋ฉด ์ด์–ด์กŒ๋˜ ์—ฐ๊ฒฐ์ด ๋Š๊ธฐ๊ฒŒ ๋˜์–ด์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ํ™”๋ฉด์˜ ๋‚ด์šฉ์„ ๊ฐฑ์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์‹œ request๋ฅผ ํ•˜๊ณ  response๋ฅผ ํ•˜๋ฉฐ ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ๊ฐฑ์‹ ํ•˜๊ฒŒ ๋˜๋ฉฐ, ์ด๋Š” ์—„์ฒญ๋‚œ ์ž์›๋‚ญ๋น„์™€ ์‹œ๊ฐ„๋‚ญ๋น„๋ฅผ ์ดˆ๋ž˜ํ•˜๊ณ  ๋ง ๊ฒƒ์ด๋‹ค.
  • ํ•˜์ง€๋งŒ XMLHttpRequest ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์— request ํ•˜๋Š” ๊ฒฝ์šฐ, JSON์ด๋‚˜ XMLํ˜•ํƒœ๋กœ ํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ›์•„ ๊ฐฑ์‹ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋งŒํผ์˜ ์ž์›๊ณผ ์‹œ๊ฐ„์„ ์•„๋‚„ ์ˆ˜ ์žˆ๋‹ค.

 

AJAX์˜ ์žฅ์ 

  • ์›น ํŽ˜์ด์ง€์˜ ์†๋„ ํ–ฅ์ƒ
  • ์„œ๋ฒ„์˜ ์ฒ˜๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์„œ๋ฒ„์—์„œ Data๋งŒ ์ „์†กํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์ „์ฒด์ ์ธ ์ฝ”๋”ฉ์˜ ์–‘์ด ์ค„์–ด๋“ ๋‹ค.
  • ๊ธฐ์กด ์›น์—์„œ๋Š” ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋˜ ๋‹ค์–‘ํ•œ UI๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค. (์‚ฌ์ง„์˜ ์ œ๋ชฉ์ด๋‚˜ ํƒœ๊ทธ๋ฅผ ํŽ˜์ด์ง€์˜ ๋ฆฌ๋กœ๋“œ ์—†์ด ์ˆ˜์ •๊ฐ€๋Šฅ)

 

AJAX์˜ ๋‹จ์ 

  • ํžˆ์Šคํ† ๋ฆฌ ๊ด€๋ฆฌ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํŽ˜์ด์ง€ ์ด๋™์—†๋Š” ํ†ต์‹ ์œผ๋กœ ์ธํ•œ ๋ณด์•ˆ์ƒ์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค.
  • XMLHttpRequest๋ฅผ ํ†ตํ•ด ํ†ต์‹ ํ•˜๋Š” ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž์—๊ฒŒ ์•„๋ฌด๋Ÿฐ ์ง„ํ–‰ ์ •๋ณด๊ฐ€ ์ฃผ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค.
    = ์š”์ฒญ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜๋Š”๋ฐ ์‚ฌ์šฉ์ž๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋– ๋‚˜๊ฑฐ๋‚˜ ์˜ค์ž‘๋™ํ•  ์šฐ๋ ค๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค.
  • HTTP ํด๋ผ์ด์–ธํŠธ์˜ ๊ธฐ๋Šฅ์ด ํ•œ์ •๋˜์–ด ์žˆ๋‹ค.
  • AJAX๋ฅผ ์“ธ ์ˆ˜ ์—†๋Š” ๋ธŒ๋ผ์šฐ์ €์— ๋Œ€ํ•œ ๋ฌธ์ œ ์ด์Šˆ๊ฐ€ ์žˆ๋‹ค.
  • Script๋กœ ์ž‘์„ฑ๋˜๋ฏ€๋กœ ๋””๋ฒ„๊น…์ด ์šฉ์ดํ•˜์ง€ ์•Š๋‹ค.
  • ๋™์ผ-์ถœ์ฒ˜ ์ •์ฑ…์œผ๋กœ ์ธํ•˜์—ฌ ๋‹ค๋ฅธ ๋„๋ฉ”์ธ๊ณผ๋Š” ํ†ต์‹ ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. (Cross-Domain๋ฌธ์ œ)

 

 


 

XMLHttpRequest API์ธ Axios์™€ Fetch ์†Œ๊ฐœ

 

๋น„๋™๊ธฐ ํ†ต์‹ ์˜ ๋ชฉ์ 

1) ํŽ˜์ด์ง€๋ฅผ ๋ฆฌ๋กœ๋”ฉํ•˜์ง€ ์•Š๊ณ  ์ปจํ…์ธ ๋งŒ ๋ฐ”๋€Œ๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด API ํ†ต์‹ ์„ ํ•œ๋‹ค.
2) API๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ๋žœ๋”๋ง ์—†์ด ์ปจํŠธ๋กค๋Ÿฌ๋กœ๋งŒ์œผ๋กœ๋„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 


 

fetch

 

1) ์›๊ฒฉ API๋ฅผ ๊ฐ„ํŽธํ•˜๊ฒŒ ํ˜ธ์ถœํ•˜๋Š” Built-in API๋กœ ๋ณ„๋„์˜ ์„ค์น˜ ์—†์ด ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜์ด๋‹ค.
2) window ๊ฐ์ฒด์— ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ, HTTP Pipeline(Request/Response)๋ฅผ ์œ„ํ•œ Javascript Interface์ด๋‹ค.

 

fetch ํƒ„์ƒ ๊ณผ์ •

1. ํด๋ผ์ด์–ธํŠธ ๋‹จ์—์„œ ์ง์ ‘ http์š”์ฒญ ์‘๋‹ต๋ฐ›๋Š” ๊ณผ์ •์€ ๋งค์šฐ ๋ณต์žกํ–ˆ๋‹ค.
2. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋„์›€์„ ๋ฐ›์œผ๋ฉด ๋ฒˆ๋“ค๋Ÿฌ ํฌ๊ธฐ ๊ฐ€์ค‘๋๋‹ค.
3. ๋‚ด์žฅํ•จ์ˆ˜ fetch ๋“ฑ์žฅ

 

fetch('URL' [, OptionObj]) => Promise

fetch ํ•จ์ˆ˜์˜ ๋ฆฌํ„ด ๊ฐ’์€ Promise๊ฐ์ฒด๋‹ค.

API ํ˜ธ์ถœ์ด ์„ฑ๊ณตํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ์‘๋‹ต(response) ๊ฐ์ฒด๋ฅผ resolveํ•˜๊ณ , ์‹คํŒจํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” error ๊ฐ์ฒด๋ฅผ rejectํ•œ๋‹ค.

fetch('https://jsonplaceholder.typicode.com/posts/1').then((response) =>
  console.log(response)
);

// Response {status: 200, ok: true, redirected: false, type: "cors",

 

1) GET ํ˜ธ์ถœ

๋Œ€๋ถ€๋ถ„์˜ REST API๋“ค์€ JSON ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‘๋‹ตํ•œ๋‹ค. ์‘๋‹ต(response) ๊ฐ์ฒด๋Š” json() ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด JSON ํฌ๋ฉง์˜ ์‘๋‹ต ์ „๋ฌธ์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then((response) => response.json())
  .then((data) => console.log(data));

// { "userId": 1, "id": 1, "title": "hi"}

 

2) POST ํ˜ธ์ถœ

์›๊ฒฉ API์—์„œ ๊ด€๋ฆฌํ•˜๊ณ  ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ์š”์ฒญ ์ „๋ฌธ(๋ณด๋‚ผ ๋‚ด์šฉ, req.body์— ๋“ค์–ด๊ฐˆ ๋‚ด์šฉ) ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” POST ๋ฐฉ์‹์˜ HTTP ํ†ต์‹ ์ด ํ•„์š”ํ•˜๋‹ค.


1) method ์˜ต์…˜์„ POST๋กœ ์ง€์ •ํ•ด์ฃผ๊ณ ,
2) headers ์˜ต์…˜์„ ํ†ตํ•ด JSON ํฌ๋ฉง์„ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์•Œ๋ ค์ค˜์•ผ ํ•˜๋ฉฐ,
3) body ์˜ต์…˜์— ์š”์ฒญ ์ „๋ฌธ์„ JSON ํฌ๋ฉง์œผ๋กœ ์ง๋ ฌํ™”ํ™”์—ฌ ์„ค์ •ํ•ด์ค€๋‹ค.

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'Test', body: 'I am testing!', userId: 1 }),
}).then((response) => console.log(response));

// Response {
//	type: "cors", 
//	url: "https://jsonplaceholder.typicode.com/posts",
//	redirected: false, status: 201, ok: true,
//	… }


์‘๋‹ต ๊ฐ์ฒด์˜ json() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์‘๋‹ต ์ „๋ฌธ์„ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค.

fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ title: 'Test', body: 'I am testing!', userId: 1 }),
})
  .then((response) => response.json())
  .then((data) => console.log(data));

// {title: "Test", body: "I am testing!", userId: 1, id: 101}

 

Node ์ฝ”๋“œ ์˜ˆ์‹œ

videoPlayer.addEventListener("ended", ()=>registerView()); 

const registerView = () => {
	const videoId = window.location.href.split("/videos/")[1];
    fetch(`/api/${videoId}/view`, { method: "POST", }
}
  
apiRouter.post(routes.registerView, postRegisterView); 

const postRegisterView = async (req, res) => {
  const {
    params: { id },
  } = req;
  try {
    const video = await Video.findById(id);
    video.views += 1;
    video.save();
    res.status(200);
  } catch (error) {
    res.status(400);
  } finally {
    res.end();
  }
};

 

[๋ณด๋„ˆ์Šค] ์‚ฌ์šฉ์„ฑ ๊ฐœ์„ 

fetch() ํ•จ์ˆ˜๋Š” ์‚ฌ์šฉ๋ฒ•์ด ์•„์ฃผ ๊ฐ„๋‹จํ•˜์ง€๋งŒ, ๊ณ„์† ์‚ฌ์šฉํ•˜๋‹ค๋ณด๋ฉด ๋˜‘๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋ฐ˜๋ณต๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ์–ป๊ธฐ ์œ„ํ•ด์„œ response.json()์„ ๋งค๋ฒˆ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜, ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ผ ๋•Œ, HTTP ์š”์ฒญ ํ—ค๋”์— "Content-Type": "application/json"๋กœ ์„ค์ •ํ•ด์ฃผ๋Š” ๋ถ€๋ถ„์€ ์ง€๋ฃจํ•˜๊ฒŒ ๋А๊ปด์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด์— ์‚ฌ์šฉํ•˜๋˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ๋น„๊ตํ•ด๋ดค์„ ๋•Œ, fetch() ํ•จ์ˆ˜์˜ Promise ๊ธฐ๋ฐ˜์˜ API๊ฐ€ ์ข€ ํˆฌ๋ฐ•ํ•˜๋‹ค๊ณ  ๋А๋‚„ ์ˆ˜ ์žˆ๋‹ค.

์ด๋Ÿด ๋•Œ๋Š” fetch() ํ•จ์ˆ˜๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š”, ๋ณธ์ธ ์ž…๋ง›์— ๋งž๊ฒŒ ๋ณ„๋„์˜ ํ•จ์ˆ˜๋‚˜ ๋ชจ๋“ˆ๋กœ ๋นผ์„œ ์‚ฌ์šฉํ•˜์‹œ๊ธฐ๋ฅผ ์ถ”์ฒœํ•œ๋‹ค. ๋‚˜๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ํ”„๋กœ์ ํŠธ์˜ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด async/await ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ HTTP ๋ฐฉ์‹๋ณ„๋กœ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋ชจ๋“ˆํ™”ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณค ํ•œ๋‹ค.

async function post(host, path, body, headers = {}) {
  const url = `https://${host}/${path}`;
  const options = {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', ...headers },
    body: JSON.stringify(body),
  };
  const res = await fetch(url, options);
  const data = await res.json();
  if (res.ok) {
    return data;
  } else {
    throw Error(data);
  }
}
post('jsonplaceholder.typicode.com', 'posts', {
  title: 'Test',
  body: 'I am testing!',
  userId: 1,
})
  .then((data) => console.log(data))
  .catch((error) => console.log(error));

์ด ๋ฐฉ๋ฒ•์œผ๋กœ API ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, Node.js ํ™˜๊ฒฝ์—์„œ๋„ node-fetch๋‚˜ unfetch์™€ ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€๋Šฅํ•˜๋‹ค. ์ธํ„ฐ๋„ท ์ต์Šคํ”Œ๋กœ๋Ÿฌ์—์„œ๋Š” fetch() ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋‹ˆ ์ฐธ๊ณ ํ•ด์„œ ์‚ฌ์šฉํ•˜์ž.

 

 


 

Axios

Axios ๋Š” ์จ๋“œํŒŒํ‹ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ์ด ๋ณด์žฅ๋˜๋ฉฐ, ์‚ฌ์šฉํ•˜๊ธฐ๋„ ์‰ฌ์›Œ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค.

 

React ์ฝ”๋“œ ์˜ˆ์‹œ

// $ npm install axios

const getMovies = async () => {
  const {
    data: {
      data: { movies },
    },
  } = await axios.get(
    'https://yts-proxy.nomadcoders1.now.sh/list_movies.json?sort_by=date_added'
  );
  this.setState({ movies, isLoading: false });
};

axios๋Š” HTTP request ์š”์ฒญ์„ ๊ฐ„์†Œํ™”ํ•œ๋‹ค.

๋ฐ˜์‘ํ˜•