๐ Fetch API ์ผ๋ก AJAX ์์ฒญํ๊ธฐ
์๋ฐ์คํฌ๋ฆฝํธ AJAX ์์ฒญ ๋ฐฉ์
์ ํต์ ์ผ๋ก XMLHttpRequest() ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ์์ฒญํ๋ ๋ฐฉ๋ฒ์ด ์์ง๋ง ๋ฌธ๋ฒ์ด ๋ํดํ๊ณ ๊ฐ๋
์ฑ๋ ์ข์ง ์๋ค. ๋ฐ๋ผ์ ์ด๋ฒ์๊ฐ์๋ ์๋ฐ์คํฌ๋ฆฝํธ AJAX ํต์ ์ ์ต์ ๊ธฐ์ ์ธ fetch() ๋ฉ์๋ ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๋ณผ ์์ ์ด๋ค.
XML Http Request ๋ฐฉ์
xmlhttprequest ๊ฐ์ฒด๋ฅผ ์ด์ฉํ ์ ํต์ ์ธ ์ด์ฐฝ๊ธฐ ๋น๋๊ธฐ ์๋ฒ ์์ฒญ ๋ฐฉ์์ด๋ค. ์ฑ๋ฅ์๋ ๋ฌธ์ ๋ ์์ง๋ง ์ฝ๋๊ฐ ๋ณต์กํ๊ณ ๊ฐ๋ ์ฑ์ด ์ข์ง ์๋ค๋ ๋จ์ ์ด ์์๋ค.
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState == XMLHttpRequest.DONE && httpRequest.status == 200) {
document.getElementById("text").innerHTML = httpRequest.responseText;
}
}
httpRequest.open("GET", "ajax_intro_data.txt", true);
httpRequest.send();
Fetch API ๋ฐฉ์
์ด๋ฒคํธ ๊ธฐ๋ฐ์ธ XMLHttpRequest๊ณผ๋ ๋ฌ๋ฆฌ fetch API๋ Promise ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ด ๋น๋๊ธฐ ์ฒ๋ฆฌ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ ์ ๋ง๋ ํํ์ด๋ค. ๊ทธ๋์ then์ด๋ catch ์ ๊ฐ์ ์ฒด์ด๋์ผ๋ก ์์ฑํ ์ ์๋ค๋ ์ฅ์ ์ด ์๋ค. ๋ํ fetch API๋ JS ๊ธฐ๋ณธ ๊ธฐ๋ฅ ์ด๊ธฐ ๋๋ฌธ์, JQuery์ ๊ฐ์ด CDN ๊ณผ ๊ฐ์ ๋ค๋ฅธ ์์ ์ ํ์ง ์์๋ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ค.
fetch('ajax_intro_data.txt')
.then( response => response.text() )
.then( text => { document.getElementById("#t").innerHTML = text; } )
/* 'fetch('์๋ฒ์ฃผ์')' ๋ ์น ๋ธ๋ผ์ฐ์ ์๊ฒ '์ด ์๋ฒ์ฃผ์๋ก ์์ฒญํด์ค' ๋ผ๋ ์๋ฏธ์ด๊ณ ,
๋ค์ .then์ด ๋ถ์ผ๋ฉด '์์ฒญ ๋๋๊ณ ๋์ ์ด ํ ์ผ์ ํด์ค!' ๋ผ๋ ๊ฒ์ด๋ค. */
fetch ๋ฌธ๋ฒ ์ฌ์ฉ๋ฒ
fetch("https://jsonplaceholder.typicode.com/posts", option)
.then(res => res.text())
.then(text => console.log(text));
- fetch ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฒซ ๋ฒ์งธ ์ธ์์ ์์ฒญํ url์ด ๋ค์ด๊ฐ๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก http ๋ฉ์๋ ์ค GET์ผ๋ก ๋์ํ๋ค.
- fetch๋ฅผ ํตํด ajax๋ฅผ ํธ์ถ ์ ํด๋น ์ฃผ์์ ์์ฒญ์ ๋ณด๋ธ ๋ค์, ์๋ต ๊ฐ์ฒด(Promise object Response)๋ฅผ ๋ฐ๋๋ค.
- ๊ทธ๋ฌ๋ฉด ์ฒซ ๋ฒ์งธ then์์ ๊ทธ ์๋ต์ ๋ฐ๊ฒ๋๊ณ , res.text() ๋ฉ์๋๋ก ํ์ฑํ text๊ฐ์ ๋ฆฌํดํ๋ค.
- ๊ทธ๋ฌ๋ฉด ๊ทธ ๋ค์ then์์ ๋ฆฌํด๋ฐ์ text ๊ฐ์ ๋ฐ๊ณ , ์ํ๋ ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ฒ ๋๋ค.
๊ฐ๋ฐ์ ๋๊ตฌ์ ๋คํธ์ํฌ ํญ์ ๊ฐ๋ณด๋ฉด fetch๋ฅผ ํตํด ์ป์ด์จ ๋ฐ์ดํฐ๋ฅผ ๋ณผ์ ์๋ค.
fetch์ response ์์ฑ
fetch๋ฅผ ํตํด ์์ฒญ์ ํ๊ณ ์๋ฒ๋ก๋ถํฐ ๊ฐ์ ์๋ต ๋ฐ์ผ๋ฉด .then์ ํตํด ํจ์์ ์ธ์์ ๋ด๊ธฐ๊ฒ ๋๋๋ฐ ์ด ๊ฐ์ Response๊ฐ์ฒด๋ก์ ์ฌ๋ฌ๊ฐ์ง ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ค.
ํ์ํ ๋ณ์๊ฐ์ด๋ ๋ฉ์๋๋ฅผ ๋ฝ์๋ด์ ๊ฐ์ ์ป์ผ๋ฉด ๋๋ค.
- response.status – HTTP ์ํ ์ฝ๋(์: 200)
- response.ok – HTTP ์ํ ์ฝ๋๊ฐ 200๊ณผ 299 ์ฌ์ด์ผ ๊ฒฝ์ฐ true
- response.body ใ ก ๋ด์ฉ
- response.text() – ์๋ต์ ์ฝ๊ณ ํ ์คํธ๋ฅผ ๋ฐํํ๋ค,
- response.json() – ์๋ต์ JSON ํํ๋ก ํ์ฑํ๋ค,
- response.formData() – ์๋ต์ FormData ๊ฐ์ฒด ํํ๋ก ๋ฐํํ๋ค.
- response.blob() – ์๋ต์ Blob(ํ์ ์ด ์๋ ๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ) ํํ๋ก ๋ฐํํ๋ค.
- response.arrayBuffer() – ์๋ต์ ArrayBuffer(๋ฐ์ด๋๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ๋ก์ฐ ๋ ๋ฒจ ํ์์ผ๋ก ํํํ ๊ฒ) ํํ๋ก ๋ฐํํ๋ค.
โ ๏ธ ์ฃผ์
์๋ต ์๋ฃ ํํ ๋ฐํ ๋ฉ์๋๋ ํ๋ฒ๋ง ์ฌ์ฉ ํ ์ ์๋ค.
๋ง์ผ response.text()๋ฅผ ์ฌ์ฉํด ์๋ต์ ์ป์๋ค๋ฉด ๋ณธ๋ฌธ์ ์ฝํ ์ธ ๋ ๋ชจ๋ ์ฒ๋ฆฌ ๋ ์ํ์ด๊ธฐ ๋๋ฌธ์ ๋ค์ ๋ response.json() ์จ์ค๋ ๋์ํ์ง ์๊ฒ ๋๋ค.
Fetch - CRUD ์์ฒญํ๊ธฐ
http ์์ฒญ์๋ get, post ๋ฟ๋ง ์๋๋ผ put, delete ๊ฐ์ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋ค.
fetch() ๋ฉ์๋๋ก ์ด๋ป๊ฒ http ์์ฒญ์ด๋ ์กฐํฉํด์ ์ฌ์ฉํ๋์ง ๊ทธ๋ฆฌ๊ณ ๊ทธ ๋ฌธ๋ฒ์ ์์๋ณด๋ ์๊ฐ์ ๊ฐ์ ธ๋ณด์.
HTTP Method ์ข ๋ฅ (CRUD)
METHOD | ์ญํ |
POST | POST๋ฅผ ํตํด ํด๋น URI๋ฅผ ์์ฒญํ๋ฉด ๋ฆฌ์์ค๋ฅผ ์์ฑ |
GET | GET๋ฅผ ํตํด ํด๋น ๋ฆฌ์์ค๋ฅผ ์กฐํํฉ๋๋ค. ๋ฆฌ์์ค๋ฅผ ์กฐํํ๊ณ ํด๋น ๋ํ๋จผํธ์ ๋ํ ์์ธํ ์ ๋ณด๋ฅผ ๊ฐ์ ธ |
PUT | PUT๋ฅผ ํตํด ํด๋น ๋ฆฌ์์ค๋ฅผ ์์ |
DELETE | DELETE๋ฅผ ํตํด ๋ฆฌ์์ค๋ฅผ ์ญ์ |
โ
fetch - GET Method
GET : ์กด์ฌํ๋ ์์์ ์์ฒญ
→ ๋จ์ํ ์๊ฒฉ API์ ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋ ์ฐ์
→ fetchํจ์๋ ๋ํดํธ๋ก GET ๋ฐฉ์์ผ๋ก ์๋ํ๊ณ , ์ต์ ์ธ์๊ฐ ํ์ ์์.
→ ์๋ต(response) ๊ฐ์ฒด๋ json() ๋ฉ์๋๋ฅผ ์ ๊ณตํ๊ณ , ์ด ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ์๋ต(response) ๊ฐ์ฒด๋ก๋ถํฐ JSON ํํ์ ๋ฐ์ดํฐ๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ์ป์ ์ ์์.
fetch("https://jsonplaceholder.typicode.com/posts/1") // posts์ id 1์ธ ์๋ฆฌ๋จผํธ๋ฅผ ๊ฐ์ ธ์ด
.then((response) => response.json())
.then((data) => console.log(data))
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit↵suscipit recusandae consequuntur …strum rerum est autem sunt rem eveniet architecto"
}
fetch - POST Method
POST : ์๋ก์ด ์์ ์์ฑ ์์ฒญ
→ ํผ ๋ฑ์ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค์ด ๋ผ ๋, ๋ณด๋ด๋ ๋ฐ์ดํฐ์ ์์ด ๋ง๊ฑฐ๋, ๋น๋ฐ๋ฒํธ ๋ฑ ๊ฐ์ธ์ ๋ณด๋ฅผ ๋ณด๋ผ ๋ POST ๋ฉ์๋ ์ฌ์ฉ
→ ์๋ก์ด ํฌ์คํธ ์์ฑ ์ํด์๋ method ์ต์ ์ POST๋ก ์ง์ ํด์ฃผ๊ณ , headers ์ต์ ์ผ๋ก JSON ํฌ๋งท ์ฌ์ฉํ๋ค๊ณ ์๋ ค์ค์ผ ํจ. body ์ต์ ์๋ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ JSON ํฌ๋งท์ผ๋ก ๋ฃ์ด์ค.
- method – HTTP ๋ฉ์๋
- headers – ์์ฒญ ํค๋๊ฐ ๋ด๊ธด ๊ฐ์ฒด(์ ์ฝ ์ฌํญ์ด ์์)
- body – ๋ณด๋ด๋ ค๋ ๋ฐ์ดํฐ(์์ฒญ ๋ณธ๋ฌธ)๋ก string์ด๋ FormData, BufferSource, Blob, UrlSearchParams ๊ฐ์ฒด ํํ
fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST", // POST
headers: { // ํค๋ ์กฐ์
"Content-Type": "application/json",
},
body: JSON.stringify({ // ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ฅผ jsonํ ํ๋ค.
title: "Test",
body: "I am testing!",
userId: 1,
}),
})
.then((response) => response.json())
.then((data) => console.log(data))
โ
fetch - PUT Method (์ ์ฒด์์ )
PUT : ์กด์ฌํ๋ ์์ ๋ณ๊ฒฝ ์์ฒญ
→ API์์ ๊ด๋ฆฌํ๋ ๋ฐ์ดํฐ์ ์์ ์ ์ํด PUT ๋ฉ์๋ ์ฌ์ฉํจ.
→ method ์ต์ ๋ง PUT์ผ๋ก ์ค์ ํ๋ค๋ ์ ๋นผ๋๊ณ ๋ POST ๋ฐฉ์๊ณผ ๋น์ท
→ ์์ ์ ์ฒด๋ฅผ body์ ๋ฐ์ดํฐ๋ก ๊ต์ฒดํด๋ฒ๋ฆผ.
fetch("https://jsonplaceholder.typicode.com/posts", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Test" // ์์ title ์๋ฆฌ๋จผํธ๋ก ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ฟ. ๋ง์น innerHTML๊ฐ์ด.
}),
})
.then((response) => response.json())
.then((data) => console.log(data))
โ
fetch - PATCH Method (๋ถ๋ถ์์ )
PATCH : ์กด์ฌํ๋ ์์ ์ผ๋ถ ๋ณ๊ฒฝ ์์ฒญ
→ body์ ๋ฐ์ดํฐ์ ์๋ง๋ ์ผ๋ถ๋ง์ ๊ต์ฒดํจ .
fetch("https://jsonplaceholder.typicode.com/posts/1", { // posts์ id 1์ธ ์๋ฆฌ๋จผํธ๋ฅผ ์์
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Test" // title๋ง ๋ฐ๊ฟ. ๋๋จธ์ง ์์๋ ๊ฑด๋ค์ง ์์.
}),
})
.then((response) => response.json())
.then((data) => console.log(data))
โ
fetch - DELETE Method
DELETE : ์กด์ฌํ๋ ์์ ์ญ์ ์์ฒญ
→ ๋ณด๋ผ ๋ฐ์ดํฐ๊ฐ ์๊ธฐ ๋๋ฌธ์ headers, body ์ต์ ์ด ํ์์์
fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "DELETE",
})
.then((response) => response.json())
.then((data) => console.log(data))
Fetch - async / await ๋ฌธ๋ฒ
fetch์ ๋ฆฌํด๊ฐ response๋ Promise๊ฐ์ฒด ์ด๋ค. ๋น์ฐํ await / async ๋ฌธ๋ฒ์ผ๋ก ๋ณด๋ค ๊ฐ๋ ์ฑ์ ๋์ด๊ฒ ์ฝ๋ฉ ํ ์ ์๋ค.
fetch("https://jsonplaceholder.typicode.com/posts", option)
.then(res => res.text())
.then(text => console.log(text));
(async () => {
let res = await fetch("https://jsonplaceholder.typicode.com/posts", option);
let text = await res.text();
console.log(text);
})() //await์ asyncํจ์๋ด์์๋ง ์ธ์ ์์ผ๋, ์ต๋ช
async ๋ฐ๋ก ์คํํจ์๋ฅผ ํตํด ํ์ฉํฉ๋๋ค.
fetch ๋ชจ๋ํ - ์ฌ์ฉ์ฑ ๊ฐ์ ํ๊ธฐ
fetch() ํจ์๋ ์ฌ์ฉ๋ฒ์ด ์์ฃผ ๊ฐ๋จํ์ง๋ง, ๊ณ์ ์ฌ์ฉํ๋ค๋ณด๋ฉด ๋๊ฐ์ ์ฝ๋๊ฐ ๋ฐ๋ณต๋๋ค๋ ๊ฒ์ ๋๋ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค์ด, ์๋ต ๋ฐ์ดํฐ์ ์ป๊ธฐ ์ํด์ response.json()์ ๋งค๋ฒ ํธ์ถํ๊ฑฐ๋, ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ๋, HTTP ์์ฒญ ํค๋์ "Content-Type": "application/json"๋ก ์ผ์ผํ ์ค์ ํด์ค์ผ ๋๊ฑฐ๋ ์จ์ผ ๋ ๊ฒ ๋ง๋ค.
ํ๋๋ฒ fetch() ๋ฅผ ์ฌ์ฉํ๋ ์ ๋๋ ๋ฌธ์ ๊ฐ ์๋์ง๋ง, ์ฌ๋ฌ๋ฒ ์ฌ์ฉํ ์ผ์ด ์์ผ๋ฉด ๋ฐ๋ก ํฌํผ ํจ์๋ฅผ ๋ง๋ค์ด ๋ชจ๋ํ๋ฅผ ํด๋๋๊ฒ ๋์ค์ ์ ๋ง ํธํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
์๋ ์ฝ๋์ ๊ฐ์ด POST ์์ฒญ์ ๋ณด๋ผ ํ์๊ฐ ์๋ค๋ฉด ํจ์๋ก ๋ฐ๋ก ๋ฏธ๋ฆฌ ๊ตฌ์ฑ์ ์ง๋๊ณ , ์ธ์๋ก ๊ฐ๋ค์ ์ ๋ฌํด ๋ฐ๋ก๋ฐ๋ก ๊ฐ์ ์๋ต ๋ฐ๋ ์์ผ๋ก ๊ณ ๊ธ ๊ตฌ์ฑ์ ํด๋๋๋ค.
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));
๊ตฌํ ๋ธ๋ผ์ฐ์ ์์ fetch ์ฌ์ฉํ๊ธฐ
fetch๋ ES6 ์ต์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ์ ์ด๋ค. ๋ฐ๋ผ์ ์ธํฐ๋ท ์ต์คํ๋ก์ด ๊ฐ์ ๊ตฌํ ๋ธ๋ผ์ฐ์ ์๋ ๋์์ ์ํ๋๋ฐ, ์ด๋๋ ๋ฐ๋ก polyfill๋ ์ฝ๋๋ฅผ ์ ์ฉํด ๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋ฌด๋ฆฌ์์ด fetch๋ฅผ ์ฌ์ฉ ํ ์ ์๋ค.
ํด๋ฆฌํ(polyfill)์ด๋ผ๋ ๋จ์ด๊ฐ ๋ญ๊ฐ ์์ํด์ ๋ณต์กํ๊ณ ์ด๋ ค์ธ๊ฒ ๊ฐ์๋ณด์ด์ง๋ง ์ง์ ํด๋ณด๋ฉด ๋งค์ฐ ๊ฐ๋จํ๋ค.
ํด๋ฆฌํ(polyfill)์ ์น ๊ฐ๋ฐ์์ ๊ธฐ๋ฅ์ ์ง์ํ์ง ์๋ ์น ๋ธ๋ผ์ฐ์ ์์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ์ฝ๋๋ฅผ ๋ปํ๋ค.
์ ๋งํฌ์์ fetch.js๋ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค์ด๋ฐ๊ณ , ์๋ง์ ๊ฒฝ๋ก๋ก src๋ฅผ ์ง์ ํ๋ฉด ๋๋ค. โ์ด๋ ๊ฒ ํด์ฃผ๋ฉด fetch api๋ฅผ ์ง์ํ๋ ์ต์ ๋ธ๋ผ์ฐ์ ๋ ๊ทธ๋๋ก ์งํํ๊ณ , ์ง์ํ์ง ์๋ ๊ตฌํ ๋ธ๋ผ์ฐ์ ๋ fectch.js๋ด์ ์๋ ํจ์๋ฅผ ํตํด ajax๊ฐ ์งํ๋๊ฒ ๋ฉ๋๋ค.
<head>
<meta charset="utf-8">
<script src="../fetch.js"></script>
</head>