2. Fetch API & CORS
ํค์๋
Fetch API๋
Promise
ReadableStream
Unicode
CORS๋
Fetch API
๋คํธ์ํฌ๋ฅผ ํตํด์ ๋ฆฌ์์ค๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ ์ธํฐํ์ด์ค
fetch()
Promise๋ฅผ ๋ฐํ
์ฒซ๋ฒ์งธ ์ธ์๋ก URL, ๋๋ฒ์งธ ์ธ์๋ก ์ต์ ๊ฐ์ฒด๋ฅผ ๋ฐ์
API ํธ์ถ์ด ์ฑ๊ณตํ์ ๋๋ response ๊ฐ์ฒด๋ฅผ resolve
์คํจํ์ ๋๋ ์์ธ(error) ๊ฐ์ฒด๋ฅผ reject
์ต์ ์ ํตํด HTTP Method, ์์ฒญ ํค๋, ์์ฒญ body ๋ฑ์ ์ค์ ๊ฐ๋ฅ
response ๊ฐ์ฒด๋ HTTP ์๋ต์ํ(status), header, body๋ฑ์ ์ฝ์ด์ฌ ์ ์์
fetch(url, options)
.then((response) => console.log("response:", response))
.catch((error) => console.log("error:", error));
Promise
์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ฌ์ฉ๋๋ ๊ฐ์ฒด
์๋ฐ์คํฌ๋ฆฝํธ๋ ํน์ ์ฝ๋์ ์คํ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ๋จผ์ ์ํ
์๋ฒ์ ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ฐ๊ธฐ ์ ์ ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ค๊ณ ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์
์๋ต์ ๋ฐ์ ๋ค์ ๋ค์ ๋ช ๋ น์ ์ํํ๋ ค๋ฉด ์ฝ๋ฐฑํจ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ฐ, ํ๋ก๋ฏธ์ค๋ ์ฝ๋ฐฑ์ด ์ค์ฒฉ๋์ด ์ฝ๋๊ฐ ์ฝ๊ธฐ ์ด๋ ค์์ง๋ ๊ฑธ ์๋ฐฉํ ์ ์์
function getData(callback) {
// new Promise() ์ถ๊ฐ
return new Promise(function(resolve, reject) {
$.get('url ์ฃผ์/products/1', function(response) {
// ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ผ๋ฉด resolve() ํธ์ถ
resolve(response);
});
});
}
// getData()์ ์คํ์ด ๋๋๋ฉด ํธ์ถ๋๋ then()
getData().then(function(tableData) {
// resolve()์ ๊ฒฐ๊ณผ ๊ฐ์ด ์ฌ๊ธฐ๋ก ์ ๋ฌ๋จ
console.log(tableData); // $.get()์ reponse ๊ฐ์ด tableData์ ์ ๋ฌ๋จ
});
ํ๋ก๋ฏธ์ค์ ์ธ๊ฐ์ง ์ํ
Pending(๋๊ธฐ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ก์ง์ด ์๋ฃ๋์ง ์์ ์ํ
Fulfilled(์ดํ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์๋ฃ๋์ด ํ๋ก๋ฏธ์ค๊ฐ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํํด์ค ์ํ
Rejected(์คํจ) : ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ์คํจํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ํ
new Promise()
๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด Pending ์ํ๊ฐ ๋จ
new Promise()
๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ ์ธํ ์ ์๊ณ , ์ฝ๋ฐฑ ํจ์์ ์ธ์๋ resolve
์ reject
resolve
๋ฅผ ์คํํ๋ฉด Fulfilled ์ํ๊ฐ ๋จ
์ดํ(์๋ฃ)์ํ๊ฐ ๋๋ฉด then()
์ ์ด์ฉํด์ ์ฒ๋ฆฌ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐ์ ์ ์์
function getData() {
return new Promise(function(resolve, reject) {
var data = 100;
resolve(data);
});
}
// resolve()์ ๊ฒฐ๊ณผ ๊ฐ data๋ฅผ resolvedData๋ก ๋ฐ์
getData().then(function(resolvedData) {
console.log(resolvedData); // 100
});
reject
๋ฅผ ์คํํ๋ฉด Reject ์ํ๊ฐ ๋จ
์คํจ์ํ๊ฐ ๋๋ฉด Error๋ฅผ catch()
๋ก ๋ฐ์ ์ ์์
function getData() {
return new Promise(function(resolve, reject) {
reject(new Error("Request is failed"));
});
}
// reject()์ ๊ฒฐ๊ณผ ๊ฐ Error๋ฅผ err์ ๋ฐ์
getData().then().catch(function(err) {
console.log(err); // Error: Request is failed
});
GET ๋ฐฉ์ ํธ์ถํ๊ธฐ
fetch("https://jsonplaceholder.typicode.com/posts/1").then((response) =>
console.log(response)
);
// ๊ฒฐ๊ณผ
Response {status: 200, ok: true, redirected: false, type: "cors", url: "https://jsonplaceholder.typicode.com/posts/1", โฆ}
๋๋ถ๋ถ์ REST API๋ JSON ํํ์ ๋ฐ์ดํฐ๋ฅผ ์๋ตํ๊ธฐ ๋๋ฌธ์ response ๊ฐ์ฒด๋ json()
๋ฉ์๋ ์ ๊ณต
์๋ต ๊ฐ์ฒด๋ก๋ถํฐ JSON ํฌ๋งท์ ์๋ต ์ ๋ฌธ์ ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ก ๋ณํํ์ฌ ์ป์ ์ ์์
{
"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"
}
POST ํธ์ถ
method ์ต์ ์ POST๋ก ์ง์ , headers ์ต์ ์ผ๋ก JSON ํฌ๋งท์ ์ฌ์ฉํ๋ค๊ณ ์๋ ค์ฃผ๊ณ , ์์ฒญ ์ ๋ฌธ์ JSON ํฌ๋งท์ผ๋ก ์ง๋ ฌํํ์ฌ body ์ต์ ์ ์ค์
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, โฆ}
๋ง์ฐฌ๊ฐ์ง๋ก response.json()
ํธ์ถํ๋ฉด ์๋ต ์ ๋ฌธ์ ๊ฐ์ฒด๋ก ์ป์ ์ ์์
{title: "Test", body: "I am testing!", userId: 1, id: 101}
json()
๋ฉ์๋ ์์ด response ์ฝ์ด์ค๊ธฐ
json()
๋ฉ์๋ ์์ด response ์ฝ์ด์ค๊ธฐfetch('http://localhost:3000/products');
// โ Promise
await fetch('http://localhost:3000/products');
// โ Response
const response = await fetch('http://localhost:3000/products');
// โ response.body๋ ReadableStream
const reader = response.body.getReader();
const chunk = await reader.read();
// โ chunk.value๋ Uint8Array ํ์
.
// โ ์๋๋ chunk.done์ด true์ผ ๋๊น์ง ๋ฐ๋ณตํด์ผ ํ๋ค.
const body = new TextDecoder().decode(chunk.value);
const data = JSON.parse(body);
response.body()๋ ReadableStream
ReadableStream์ ๋ฐ์ดํธ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์๋ ์คํธ๋ฆผ ์ ๊ณต
ReadableStream.getReader()
: Reader๋ฅผ ๋ง๋ค๊ณ ์คํธ๋ฆผ์ Reader์ ๊ณ ์ . ์คํธ๋ฆผ์ด ๊ณ ์ ๋์ด ์๋ ๋์์๋ ๋ค๋ฅธ Reader๋ฅผ ์ป์ ์ ์์
์ฝ์ด์จ ๊ฐ์ byte array -> ๋์ฝ๋ฉํด์ ์ฝ์ -> json.parse()๋ก ๊ฐ์ฒด๋ก ๋ง๋ค๊ธฐ
CORS
๋์ผ ์ถ์ฒ ์ ์ฑ (Same Origin Policy)
์ด๋ค ์ถ์ฒ์์ ๋ถ๋ฌ์จ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค์ ์ํธ์์ฉํ๋ ๊ฒ์ ์ ํํ๋ ๋ณด์๋ฐฉ์
๋ URL์ ํ๋กํ ์ฝ, ํฌํธ, ํธ์คํธ๊ฐ ๋ชจ๋ ๊ฐ์์ผ ํจ
์น ๋ธ๋ผ์ฐ์ ๋ Same Origin Policy์ ๋ฐ๋ผ ์น ํ์ด์ง์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ๊ณณ(์๋ฒ)์ด ์๋ก ๋ค๋ฅธ ์๋ฒ์ผ ๋ ์๋ฒ์์ ์ป์ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋ง์
์ด ๋ ์๋ฒ์ ์์ฒญํ๊ณ ์๋ต์ ๋ฐ์์ค๋ ๊ฑด ์งํ๋ ์ํ์ด์ง๋ง ์ฌ์ฉํ ์ ์๊ฒ ๋จ
CORS(Cross-Origin Resource Sharing, ๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ )
์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฌ์ฉํ์ฌ ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์
REST API ์๋ฒ์์ Headers์
Access-Control-Allow-Origin
์์ฑ์ ์ถ๊ฐํ๋ฉด ๋จExpress์์๋ CORS ๋ฏธ๋ค์จ์ด๋ฅผ ์ค์นํ๋ฉด ๋จ
Last updated