Fetch API & CORS

Fetch API ๋ž€

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋„คํŠธ์›Œํฌ ํ†ต์‹  API XMLHttpRequest(XMLHttp) ๊ฐ์ฒด์˜ ๋Œ€์•ˆ์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค.

const response = fetch('http://localhost:3000/products'); 
// โ†’ Promise ๋ฐ˜ํ™˜

const response = await fetch('http://localhost:3000/products'); 
// โ†’ Response ๋ฐ˜ํ™˜, response.body๋Š” ReadableStream

const reader = response.body.getReader();

const chunk = await reader.read();
// โ†’ chunk.value๋Š” Uint8Array ํƒ€์ž….
// โ†’ ์›๋ž˜๋Š” chunk.done์ด true์ผ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์•ผ ํ•œ๋‹ค.
// Generator์™€ ๋น„์Šทํ•œ๊ฒƒ ๊ฐ™๋‹ค.

const body = new TextDecoder().decode(chunk.value);
// โ†’ ์œ ๋‹ˆ์ฝ”๋“œ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์œผ๋ฏ€๋กœ decode๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€ํ™˜ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

const data = JSON.parse(body);
// โ†’ ์ตœ์ข…์ ์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด๋กœ ํŒŒ์‹ฑ

JSON์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ง€์›ํ•˜์—ฌ ์œ„ ๋ณต์žกํ•œ ๋‹จ๊ณ„ ์—†์ด ์‘๋‹ต ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

const response = await fetch('http://localhost:3000/products');
const data = await response.json(); 

XMLHttpRequest(XMLHttp)

AJAX์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ๋„คํŠธ์›Œํฌ ํ†ต์‹  API

Fetch API๋Š” ๋‹ค์Œ ๊ฐ™์€ ์ด์œ ๋กœ XMLHttp๋ฅผ ๋Œ€์ฒด ํ•˜์˜€๋‹ค.

  • Promise ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ

  • CORS default๋กœ ์ง€์›

  • HTTP/2 ์ง€์›

  • ๋” ์ง๊ด€์ ์ธ API, Response ๊ฐ์ฒด ๊ฐ€๊ณต ๋ฐ ์‚ฌ์šฉ์„ฑ ์šฉ์ด

Promise

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฐ์ฒด

๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ž€ ์–ด๋–ค ์ž‘์—…์ด ์‹คํ–‰ ์ค‘์ผ ๋•Œ ๋‹ค๋ฅธ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

Promise๋Š” ๋น„๋™๊ธฐ ์ฝœ๋ฐฑ ์ง€์˜ฅ์—์„œ ๋ฒ—์–ด๋‚˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋ฅผ ์ง๊ด€์ ์ด๊ณ  ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋˜์—ˆ๋‹ค.

Promise ๊ฐ์ฒด๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ fulfilled(์„ฑ๊ณต), rejected(์‹คํŒจ)๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋กœ ๊ฒฐ๊ณผ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด then() ํ˜ธ์ถœํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋Œ€๋ถ€๋ถ„์˜ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์€ Promise ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

ReadableStream

์›น ๋ธŒ๋ผ์šฐ์ €์™€ Node.js์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์›น API๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค. ํฐ ๋ฐ์ดํ„ฐ ํŒŒ์ผ, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ๋“ฑ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์œ ์šฉํ•˜๋ฉฐ, ๋ฐ์ดํ„ฐ ์†Œ์Šค๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

ReadableStream์„ ์ƒ์„ฑํ•˜๋ฉด ๋ฐ์ดํ„ฐ ์†Œ์Šค๊ฐ€ ์—ฌ๋Ÿฌ ์ฒญํฌ(chunk)๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์ „๋‹ฌ๋˜๋Š”๋ฐ ๋น„๋™๊ธฐ๋กœ ๋™์ž‘ํ•œ๋‹ค. ์ฆ‰, ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ๋ฒˆ์— ์ฝ์–ด๋“ค์ด์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ๋งŒํผ ์ฒญํฌ ๋‹จ์œ„๋กœ ์ฝ์–ด๋“ค ์ˆ˜ ์žˆ๊ฒŒ๋œ๋‹ค.

Fetch API๊ฐ€ Response.body๋กœ ReadableStream ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ฒญํฌ(chunk)๋ž€ ๋ฐ์ดํ„ฐ๋ฅผ ์ž‘์€ ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์–ด ๋‚˜๋ˆˆ ์กฐ๊ฐ๋“ค์„ ์˜๋ฏธํ•œ๋‹ค. ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ฒญํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ „์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ ์–ด ํšจ์œจ์ 

Unicode

์œ ๋‹ˆ์ฝ”๋“œ(Unicode)๋Š” ์ „ ์„ธ๊ณ„์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ๊ตญ์ œ ํ‘œ์ค€ ์ฝ”๋“œ ์•„์Šคํ‚ค์ฝ”๋“œ(ASCII)๋Š” ํŠน์ • ์–ธ์–ด๋‚˜ ๋ฌธ์ž ์ฒด๊ณ„๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์–‘ํ•œ ์–ธ์–ด๋ฅผ ํ‘œํ˜„ํ•˜๋Š”๋ฐ ์–ด๋ ค์›€์ด ์žˆ๋‹ค.

CORS(Cross-Origin Resource Sharing)

๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰๋˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋‹ค๋ฅธ ์ถœ์ฒ˜(origin)์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๋ณด์•ˆ ์ด์Šˆ

์›น ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ ์Šคํฌ๋ฆฝํŠธ์—์„œ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋„๋ก ์ œ์•ˆํ•˜๊ณ  ์žˆ๋‹ค.

์ถœ์ฒ˜๋Š” ํฌํŠธ๋ฒˆํ˜ธ๊นŒ์ง€ ํฌํ•จํ•˜์—ฌ ๋น„๊ตํ•œ๋‹ค.

CORS ์ด์Šˆ๊ฐ€ ํ„ฐ์ ธ๋„ ์ด๋ฏธ ์„œ๋ฒ„์—์„œ ์‘๋‹ต์ด ๋๋‚œ ์ƒํƒœ์ด๋‹ค.

์ฆ‰, ์„œ๋ฒ„์— ์š”์ฒญ์„ ํ•˜๊ณ  ์‘๋‹ต์„ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ๊นŒ์ง€ ๋ชจ๋‘ ์ง„ํ–‰๋์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ถœ์ฒ˜๊ฐ€ ๋‹ฌ๋ผ ๋ฐ์ดํ„ฐ๋ฅผ ๋ชป์“ฐ๊ฒŒ ๋ง‰์•„ ๋†“๋Š”๊ฒƒ์ด๋‹ค.

Express๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ CORS ํ•ด๊ฒฐํ•˜๊ธฐ

๋ฆฌ์†Œ์Šค๋ฅผ ์ฃผ๋Š” ๊ณณ(์„œ๋ฒ„)์—์„œ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ์ถœ์ฒ˜๊ฐ€ ๋‹ฌ๋ผ๋„ ๊ดœ์ฐฎ๋‹ค๊ณ  ์•Œ๋ ค์•ผ ํ•ด๊ฒฐ ๊ฐ€๋Šฅํ•˜๋‹ค.

HTTP Header์— Access-Control-Allow-Origin ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

Express๋Š” CORS ๋ฏธ๋“ค์›จ์–ด ์ถ”๊ฐ€ํ•˜๋ฉด ๊ฐ„๋‹จ ํ•ด๊ฒฐ

npm i cors
npm i -D @types/cors
import express from 'express';
import cors from 'cors';

const app = express();
 
app.use(cors()); // c๋กœ ์ž‘์„ฑํ–ˆ๋‹ค๊ฐ€ ๋™์ž‘์„ ์•ˆํ•ด์„œ ํ•œ์ฐธ ํ—ค๋งด

Last updated