2. Fetch API & CORS
1. Fetch API
์น ๋ธ๋ผ์ฐ์ ์์ ์ฌ์ฉํ๋ Web API ๋คํธ์ํฌ ํต์ ์ ํฌํจํ ๋ฆฌ์์ค ์ทจ๋์ ์ํ ์ธํฐํ์ด์ค๊ฐ ์ ์๋์ด ์์
์ฌ์ฉ ๋ฐฉ๋ฒ
๊ธฐ๋ณธ์ ์ธ Fetch ์์ฒญ
fetch('http://example.com/movies.json')
.then((response) => response.json())
.then((data) => console.log(data));
json()
JSON ๋ณธ๋ฌธ ์ฝํ ์ธ ๋ฅผ ์ถ์ถํ๊ธฐ ์ํด์๋ json() ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํจ json()์ ์๋ต ๋ณธ๋ฌธ ํ ์คํธ๋ฅผ JSON์ผ๋ก ํ์ฑํ ๊ฒฐ๊ณผ๋ก ์ดํํ๋, ๋ ๋ค๋ฅธ ํ๋ก๋ฏธ์ค๋ฅผ ๋ฐํ
fetch๋ฅผ ์ฌ์ฉํด JSON ๊ตฌ๋ฌธ๋ถ์ํ๊ธฐ
API์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ
.json()
๋ฉ์๋๋ฅผ ํตํด JSON ์๋ต์ JavaScript ๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋๋ ๋ฐฐ์ด๋ก ์๋์ผ๋ก ๊ตฌ๋ฌธ๋ถ์
2. Promise
Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์ ์ด ๋ง์ดํ ๋ฏธ๋์ ์๋ฃ ๋๋ ์คํจ์ ๊ทธ ๊ฒฐ๊ณผ ๊ฐ์ ๋ํ๋
Promise๋ ํ๋ก๋ฏธ์ค๊ฐ ์์ฑ๋ ์์ ์๋ ์๋ ค์ง์ง ์์์ ์๋ ์๋ ๊ฐ์ ์ํ ๋๋ฆฌ์ ๋น๋๊ธฐ ์ฐ์ฐ์ด ์ข ๋ฃ๋ ์ดํ์ ๊ฒฐ๊ณผ ๊ฐ๊ณผ ์คํจ ์ฌ์ ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฐ๊ฒฐํ ์ ์์ ํ๋ก๋ฏธ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๋น๋๊ธฐ ๋ฉ์๋์์ ๋๊ธฐ ๋ฉ์๋์ฒ๋ผ ๊ฐ์ ๋ฐํํ ์ ์์ ๊ทธ๋ ์ง๋ง ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ์๋๊ณ , ๋ฏธ๋์ ์ด๋ค ์์ ์ ๊ฒฐ๊ณผ๋ฅผ ์ ๊ณตํ๊ฒ ๋ค๋ ์ฝ์(ํ๋ก๋ฏธ์ค)์ ๋ฐํ
Promise์ ์ํ
Promise๋ ๋ค์ ์ค ํ๋์ ์ํ๋ฅผ ๊ฐ์ง
๋๊ธฐ(pending): ์ดํํ์ง๋, ๊ฑฐ๋ถํ์ง๋ ์์ ์ด๊ธฐ ์ํ
์ดํ(fulfilled): ์ฐ์ฐ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋จ
๊ฑฐ๋ถ(rejected): ์ฐ์ฐ์ด ์คํจํจ
3. ReadableStream
Streams API์ ReadableStream ์ธํฐํ์ด์ค๋ ๋ฐ์ดํธ ๋ฐ์ดํฐ๋ฅผ ์ฝ์ ์ ์๋ ์คํธ๋ฆผ์ ์ ๊ณต Fetch API๋ Response ๊ฐ์ฒด์ body ์์ฑ์ ํตํด ReadableStream์ ๊ตฌ์ฒด์ ์ธ ์ธ์คํด์ค๋ฅผ ์ ๊ณต
๊ธฐ๋ณธ์ ์ธ ์ฌ์ฉ๋ฒ
ReadableStream์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฐ์ getReader()
๋ก ์ป์ด์จ ํ ์งํ
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);
chunk.value
๋ Uint8Array ํ์ ์ด๊ธฐ ๋๋ฌธ์ string์ผ๋ก ๋ฐ๊ฟ์ค์ผ ํจTextDecoder๋ ์ฃผ์ด์ง ๋ฒํผ์ ์ธ์ฝ๋ฉ์ผ๋ก ๊ฐ์ ์ค์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ์์ด๋ก ์ฝ์ ์ ์๊ฒ ํด์ค
JSON์ ๊ธฐ๋ณธ ์ง์
const response = await fetch('http://localhost:3000/products');
const data = await response.json();
๋ค๋ฅธ HTTP Method๋ฅผ ์ฐ๊ณ ์ถ์ ๊ฒฝ์ฐ
const response = fetch(url, {
method: 'POST',
});
ํ
์คํธ ํ์ผ ํ ์ค์ฉ ์ฒ๋ฆฌํ๊ธฐ
์๋ต์์ ์ฝ์ด์ค๋ ๋ฐ์ดํฐ ์ฒญํฌ(chunk)๋ ์ค ๋จ์๋ก ๊น๋ํ๊ฒ ๋๋์ง ์์ผ๋ฉฐ, Uint8Array ํํ(๋ฌธ์์ด X) ํ ์คํธ ํ์ผ์ ๊ฐ์ ธ์์ ์ค ๋จ์๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด, '์ค' ๋จ์๋ก ๋๋๋ ์์ ์ ์ง์ ๊ตฌํํด์ผ ํจ
4. Unicode
Unicode Consortium ์ ๋์ฝ๋
์ ๋์ฝ๋(Unicode)๋ ์ ์ธ๊ณ์ ๋ชจ๋ ๋ฌธ์๋ฅผ ์ปดํจํฐ์์ ์ผ๊ด๋๊ฒ ํํํ๊ณ ๋ค๋ฃฐ ์ ์๋๋ก ์ค๊ณ๋ ์ฐ์ ํ์ค ์ ๋์ฝ๋๋ ์ ๋์ฝ๋ ํํ(Unicode Consortium)๊ฐ ์ ์ ์ด ํ์ค์๋ ISO 10646 ๋ฌธ์ ์งํฉ, ๋ฌธ์ ์ธ์ฝ๋ฉ, ๋ฌธ์ ์ ๋ณด ๋ฐ์ดํฐ๋ฒ ์ด์ค, ๋ฌธ์๋ค์ ๋ค๋ฃจ๊ธฐ ์ํ ์๊ณ ๋ฆฌ์ฆ ๋ฑ์ด ํฌํจ
๊ธฐ์กด ์ธ์ฝ๋ฉ์ ๊ท๋ชจ๋ ๋ฒ์ ๋ฉด์์ ํ์ ๋์ด ์๊ณ , ๋ค๊ตญ์ด ํ๊ฒฝ์์๋ ์๋ก ํธํ๋์ง ์๋ ๋ฌธ์ ์ ์ ํด๊ฒฐ
๐ ISO(๊ตญ์ ํ์คํ ๊ธฐ๊ตฌ)
International Organization for Standardization ์ฌ๋ฌ ๋๋ผ์ ํ์ค ์ ์ ๋จ์ฒด๋ค์ ๋ํ๋ค๋ก ์ด๋ฃจ์ด์ง ๊ตญ์ ์ ์ธ ํ์คํ ๊ธฐ๊ตฌ ๋๋ผ๋ง๋ค ๋ค๋ฅธ ์ฐ์ , ํต์ ํ์ค์ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด ๊ตญ์ ์ ์ผ๋ก ํต์ฉ๋๋ ํ์ค์ ๊ฐ๋ฐํ๊ณ ๋ณด๊ธ
๐ UCS(๊ตญ์ ๋ฌธ์ ์ธํธ)
Universal Character Set, ๋ฒ์ฉ ๋ฌธ์ ์งํฉ ISO 10646์ผ๋ก ์ ์๋ ๋ฌธ์ ์ธ์ฝ๋ฉ์ ๊ตญ์ ํ์ค
Uint8Array
Uint8Array ํ์ํ ๋ฐฐ์ด(TypedArray) ํ๋ซํผ์ ๋ฐ์ดํธ ์์๋ฅผ ๋ฐ๋ฅด๋ 8๋นํธ ๋ถํธ ์๋ ์ ์์ ๋ฐฐ์ด ๋ฐฐ์ด์ ๋ด์ฉ์ 0์ผ๋ก ์ด๊ธฐํ๋จ ๋ฐฐ์ด์ด ์์ฑ๋๋ฉด ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ํ์ค ๋ฐฐ์ด ์ธ๋ฑ์ค ๊ตฌ๋ฌธ(๋๊ดํธ ํ๊ธฐ๋ฒ)์ ์ฌ์ฉํ์ฌ ๋ฐฐ์ด์ ์์๋ฅผ ์ฐธ์กฐํ ์ ์์
5. CORS
๋์ผ ์ถ์ฒ ์ ์ฑ
(Same Origin Policy)
์น ๋ธ๋ผ์ฐ์ ๊ฐ ๊ฐ์ง ๊ธฐ๋ณธ ๋ณด์ ์ ์ฑ ์ด๋ค ์ถ์ฒ์์ ๋ถ๋ฌ์จ ๋ฌธ์๋ ์คํฌ๋ฆฝํธ๊ฐ ๋ค๋ฅธ ์ถ์ฒ์์ ๊ฐ์ ธ์จ ๋ฆฌ์์ค์ ์ํธ์์ฉํ๋ ๊ฒ์ ์ ํํ๋ ๋ณด์ ๋ฐฉ์
๐จ ์๋ฌ ๋ฉ์์ง
Access to fetch at 'http://localhost:3000/products' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
๊ฐ๋ฐ์ ๋๊ตฌ์ ๋คํธ์ํฌ ํญ์์ ์ดํด๋ณด๋ฉด ์๋ฒ์์ response ์๋ต์ ์ค์ง๋ง(๐ข 200 OK) ๋์ผ ์ถ์ฒ๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ์์ ๋งํ โ ์ค๋ฅ ๋ฐ์
์น ๋ธ๋ผ์ฐ์ ๋ Same Origin Policy์ ๋ฐ๋ผ ์น ํ์ด์ง์ ๋ฆฌ์์ค๋ฅผ ์์ฒญํ ๊ณณ(์ฌ๊ธฐ์๋ REST API ์๋ฒ)์ด ์๋ก ๋ค๋ฅธ ์ถ์ฒ(ํฌํธ๊น์ง ํฌํจ)์ผ ๋, ์๋ฒ์์ ์ป์ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋ง์ โ ๏ธ ์๋ฒ์ ์์ฒญํ๊ณ ์๋ต์ ๋ฐ์์ค๋ ๊ฒ๊น์ง๋ ์ด๋ฏธ ์งํ์ด ๋ค ๋ ์ํฉ
์ ์ฌ์ ์ผ๋ก ํด๋ก์ธ ์ ์๋ ๋ฌธ์๋ฅผ ๋ถ๋ฆฌํด, ๊ณต๊ฒฉ๋ฐ์ ์ ์๋ ๊ฒฝ๋ก๋ฅผ ์ค์ฌ์ค
CORS๋ฅผ ์ฌ์ฉํด ๊ต์ฐจ ์ถ์ฒ ์ ๊ทผ์ ํ์ฉํ ์ ์์
๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (CORS)
๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ (CORS)
Cross-Origin Resource Sharing CORS๋ HTTP์ ์ผ๋ถ๋ก, ์ด๋ค ํธ์คํธ์์ ์์ ์ ์ฝํ ์ธ ๋ฅผ ๋ถ๋ฌ๊ฐ ์ ์๋์ง ์๋ฒ์ ์ง์ ํ ์ ์๋ ๋ฐฉ๋ฒ ์ถ์ฒ๊ฐ ๋ค๋ฅธ ๊ณณ์ด์ด๋ ๊ด์ฐฎ์ผ๋ฉฐ ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ ๊ฒ์ด๋ผ๊ณ ์๋ฒ(๋ฆฌ์์ค๋ฅผ ์ ๊ณตํ๋ ๊ณณ) ์์ ์๋ ค์ค
REST API ์๋ฒ์์
Headers
์Access-Control-Allow-Origin
์์ฑ์ ์ถ๊ฐExpress์์๋ CORS ๋ฏธ๋ค์จ์ด ๋ฅผ ์ค์นํด์ ์ฌ์ฉ
์ถ๊ฐ HTTP ํค๋๋ฅผ ์ฌ์ฉํด, ํ ์ถ์ฒ์์ ์คํ ์ค์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ค๋ฅธ ์ถ์ฒ์ ์ ํํ ์์์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ๋ถ์ฌํ๋๋ก ๋ธ๋ผ์ฐ์ ์ ์๋ ค์ฃผ๋ ์ฒด์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฆฌ์์ค๊ฐ ์์ ์ ์ถ์ฒ(๋๋ฉ์ธ, ํ๋กํ ์ฝ, ํฌํธ)์ ๋ค๋ฅผ ๋ ๊ต์ฐจ ์ถ์ฒ HTTP ์์ฒญ์ ์คํ
์ฌ์ฉ ๋ฐฉ๋ฒ
ํจํค์ง ์ค์น
npm i cors
npm i -D @types/cors
CORS ๋ฏธ๋ค์จ์ด ์ฌ์ฉ
import express from 'express';
import cors from 'cors';
const app = express();
app.use(cors());
Last updated