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

Frontend Dev/๐Ÿฅ ์ฝ”๋“œ์Šคํ…Œ์ด์ธ  FE ๋ถ€ํŠธ์บ ํ”„

Section2 Unit10 [Web Server] ๊ธฐ์ดˆ - CORS & Mini Node Server

๋ฐ˜์‘ํ˜•


Section2 Unit10 [Web Server] ๊ธฐ์ดˆ
- CORS & Http ๋ชจ๋“ˆ๋กœ ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ(Mini Node Server)

 

๐Ÿ“Œ Chapter1. CORS

 • ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ (Cross-Origin Resource Sharing, CORS)๋Š” ์ถ”๊ฐ€ HTTP ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ํ•œ ์ถœ์ฒ˜์—์„œ ์‹คํ–‰ ์ค‘์ธ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ์„ ํƒํ•œ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ๋ธŒ๋ผ์šฐ์ €์— ์•Œ๋ ค์ฃผ๋Š” ์ฒด์ œ์ด๋‹ค.

→ ๋ธŒ๋ผ์šฐ์ €๋Š” SOP์— ์˜ํ•ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ๋ง‰์ง€๋งŒ, CORS๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ ‘๊ทผ ๊ถŒํ•œ์„ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

 • SOP(Same-Origin Policy. ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…)๋Š” ๊ฐ™์€ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋งŒ ๊ณต์œ ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ •์ฑ…์ด๋‹ค. ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…์€ ์ž ์žฌ์ ์œผ๋กœ ํ•ด๋กœ์šธ ์ˆ˜ ์žˆ๋Š” ๋ฌธ์„œ๋ฅผ ๋ถ„๋ฆฌํ•จ์œผ๋กœ์จ ๊ณต๊ฒฉ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ค„์—ฌ์ค€๋‹ค. (ํ•ดํ‚น ๋“ฑ์˜ ์œ„ํ˜‘์—์„œ ๋ณด๋‹ค ์•ˆ์ „ํ•ด์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ฆฌ๋ณธ์ ์œผ๋กœ SOP๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.)

 • ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„๋ฅผ ๋”ฐ๋กœ ๊ฐœ๋ฐœํ•˜๋ฉด ๋‘˜์˜ ์ถœ์ฒ˜๋Š” ๋‹ฌ๋ผ์ง€๋Š”๋ฐ, ํด๋ผ์ด์–ธํŠธ ๊ฐœ๋ฐœ์‹œ ์„œ๋ฒ„์—์„œ ์ •๋ณด๋ฅผ ๋ฐ›์•„์˜ฌ ๊ฒฝ์šฐ๋Š” ๋„ˆ๋ฌด๋‚˜๋„ ๋งŽ๋‹ค.

SOP๋Š” ๋‹ค๋ฅธ ์‚ฌ์ดํŠธ์™€์˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ ๋ฅผ ์ œํ•œํ•˜๊ธฐ ๋•Œ๋ฌธ์— CORS๋ฅผ ํ†ตํ•ด ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ›์•„์™€์•ผ ํ•œ๋‹ค. 

 

โญ๏ธ ๊ณผ์ œ. Mini Node Server

๐Ÿ”ฅ Node.js์˜ http ๋ชจ๋“ˆ๋กœ ์›น ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

→ Node.js์—์„œ ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์“ฐ๊ธฐ ์œ„ํ•ด fs ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๋“ฏ์ด, HTTP ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•ด HTTP ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

 ๋ธŒ๋ผ์šฐ์ €์—๋Š” ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•ด fetch ๊ฐ™์€ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋„๊ตฌ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค. ์„œ๋ฒ„๋Š” ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์˜ HTTP ์š”์ฒญ์— ๋งž๊ฒŒ ์‘๋‹ต์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค. Node.js๋Š” HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ฑฐ๋‚˜, ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋„๊ตฌ๋“ค์„ ์ œ๊ณตํ•œ๋‹ค. HTTP ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์‘๋‹ต์„ ๋ณด๋‚ด ์ฃผ๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์›น ์„œ๋ฒ„(Web Server)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

 

๐Ÿ“Ž ๊ณต์‹ ๊ฐ€์ด๋“œ ๋ฌธ์„œ: HTTP ํŠธ๋žœ์žญ์…˜ ํ•ด๋ถ€(Anatomy of an HTTP Transaction)

 

โœ”๏ธ Bare Minimum Requirement

- ์ด๋ฒˆ ์Šคํ”„๋ฆฐํŠธ์— ์ด๋ฏธ ํด๋ผ์ด์–ธํŠธ, http ์„œ๋ฒ„๊ฐ€ ๋ชจ๋‘ ์ž‘์„ฑ๋˜์–ด ์žˆ๋‹ค. HTTP ํŠธ๋žœ์žญ์…˜ ํ•ด๋ถ€๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ Mini-Node-Server๋ฅผ ์™„์„ฑํ•˜๋ฉด ๋œ๋‹ค.

 

 • POST์— ๋ฌธ์ž์—ด์„ ๋‹ด์•„ ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ๋Š” HTTP ๋ฉ”์‹œ์ง€์˜ body(payload)๋ฅผ ์ด์šฉํ•ฉ๋‹ˆ๋‹ค.

 • ์„œ๋ฒ„๋Š” ์š”์ฒญ์— ๋”ฐ๋ฅธ ์ ์ ˆํ•œ ์‘๋‹ต์„ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 • CORS ๊ด€๋ จ ํ—ค๋”๋ฅผ OPTIONS ์‘๋‹ต์— ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • ํด๋ผ์ด์–ธํŠธ์˜ preflight request์— ๋Œ€ํ•œ ์‘๋‹ต์„ ๋Œ๋ ค์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    • preflight request์— ๋Œ€ํ•œ ์‘๋‹ต ํ—ค๋”๋Š” ์ด๋ฏธ ์ž‘์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

Endpoint(URL) Method ๊ธฐ๋Šฅ
/lower POST ๋ฌธ์ž์—ด์„ ์†Œ๋ฌธ์ž๋กœ ๋งŒ๋“ค์–ด ์‘๋‹ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค
/upper POST ๋ฌธ์ž์—ด์„ ๋Œ€๋ฌธ์ž๋กœ ๋งŒ๋“ค์–ด ์‘๋‹ตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค

 

๊ตฌํ˜„๊ณผ์ •

๐Ÿ’ก TIP. nodemon ์„ค์น˜

์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ์„œ๋ฒ„๋ฅผ ๋งค๋ฒˆ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์•ผ ํ•˜๋Š”๋ฐ, nodemon์„ ์‚ฌ์šฉํ•˜๋ฉด ์ด๋ฅผ ์ž๋™์œผ๋กœ ํ•ด์ค€๋‹ค.

npm install nodemon

// package.json์˜ scripts์— ์ถ”๊ฐ€
"start": "nodemon server/basic-server.js"

npm start๋กœ ์„œ๋ฒ„ ์‹คํ–‰

 

 1. http ๋ชจ๋“ˆ ํ•™์Šต

 ์„น์…˜1๊ณผ ์„น์…˜2์˜ ์ดˆ๋ฐ˜๋ถ€์— Node.js๋ฅผ ์Šค์ณ์ง€๋‚˜๊ฐ€๋“ฏ ๋ฐฐ์› ์—ˆ์ง€๋งŒ ๊ธฐ์–ต๋‚˜์ง€ ์•Š๋Š” ๋ฌด์ง€ ์ƒํƒœ…

 Node.js๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณธ ์ ์ด ์—†์–ด์„œ http ๋ชจ๋“ˆ๋กœ ์›น ์„œ๋ฒ„๋ฅผ ์–ด๋–ป๊ฒŒ ๋งŒ๋“œ๋Š”์ง€ ๋ถ€ํ„ฐ ๊ณต๋ถ€ํ•ด์•ผ ํ–ˆ๋‹ค. ๊ณต์‹๋ฌธ์„œ์˜ HTTP ํŠธ๋žœ์žญ์…˜ ํ•ด๋ถ€๋ฅผ ์ฐฌ์ฐฌํžˆ ์ฝ์–ด๋ดค์ง€๋งŒ ๋ชจ๋ฅด๋Š” ๊ฐœ๋…์ด ๋„ˆ๋ฌด ๋งŽ๊ณ , ์ดํ•ด๊ฐ€ ์ž˜ ๋˜์ง€ ์•Š์•„์„œ ๊ตฌ๊ธ€๋ง๊ณผ ์ฑ…(๋งˆ์นจ ์˜ˆ์ „์— Node.js๋„ ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ์—ˆ๋˜ ์š•์‹ฌ์— ๊ตฌ๋งคํ–ˆ๋˜)์„ ํ†ตํ•ด ํ•™์Šต์„ ํ–ˆ๋‹ค. ์ฑ…์ด ์ •๋ฆฌ๊ฐ€ ์ž˜ ๋˜์–ด ์žˆ์–ด์„œ ์ดํ•ดํ•˜๊ธฐ ํŽธํ–ˆ๋‹ค.

 

์•„๋ž˜๋Š” ์ฑ… ๋ณด๋ฉด์„œ ๊ฐ„๋žตํ•˜๊ฒŒ ํ•™์Šตํ•œ ๋‚ด์šฉ ์ •๋ฆฌ ๐Ÿ™‚

 

 ๐Ÿ‘ฉ๐Ÿป‍๐Ÿ’ป http ๋ชจ๋“ˆ๋กœ ์„œ๋ฒ„ ๋งŒ๋“ค๊ธฐ

// http ๋ชจ๋“ˆ ์‚ฌ์šฉ 
const http = require("http");

/* 
  http ๋ชจ๋“ˆ์˜ createServer ๋ฉ”์„œ๋“œ 
  ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ request(์š”์ฒญ)์™€ response(์‘๋‹ต)๋ฅผ ๋ฐ›์Œ 
  → createServer๋ฅผ ์—ฌ๋Ÿฌ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅ
*/
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-type': 'text/html; charset=utf-8' });
  res.write('<h1>HELLO :)</h1>');
  res.end('<p>Hello Server</p>');
  /*
    writeHead ์‘๋‹ต์— ๋Œ€ํ•œ ์ •๋ณด ๊ธฐ๋ก (setHeader๋Š” ํ•˜๋‚˜ํ•˜๋‚˜ ์ง€์ •)
    write ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ผ ๋ฐ์ดํ„ฐ
    end ์‘๋‹ต์ข…๋ฃŒ ๋ฉ”์„œ๋“œ๋กœ ์ธ์ˆ˜๊ฐ€ ์žˆ์œผ๋ฉด ๊ทธ ๋ฐ์ดํ„ฐ๋„ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ด๊ณ  ์‘๋‹ต ์ข…๋ฃŒ
    (end๋Š” ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•จ์ˆ˜๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ์‹ถ์œผ๋ฉด return์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ)

    → ์œ„์˜ ์˜ˆ์ œ๋Š” <h1>HELLO :)</h1>์™€ <p>Hello Server</p> ๋ฌธ์ž์—ด์„ ํด๋ผ์ด์–ธํŠธ๋กœ ๋ณด๋‚ธ ํ›„ ์‘๋‹ต ์ข…๋ฃŒ
    → ๋ธŒ๋ผ์šฐ์ €๋Š” ์‘๋‹ต ๋‚ด์šฉ์„ ๋ฐ›์•„์„œ ๋ Œ๋”๋ง
  */
}) 
  // createServer ๋ฉ”์„œ๋“œ ๋’ค์— listen ๋ฉ”์„œ๋“œ(ํฌํŠธ ๋ฒˆํ˜ธ์™€ ์ฝœ๋ฐฑ ํ•จ์ˆ˜)๋กœ ์„œ๋ฒ„ ์—ฐ๊ฒฐ
  .listen(8080, () => { 
    console.log("PORT 8080");
  })
  

/* listen ๋ฉ”์„œ๋“œ์— ์ฝœ๋ฐฑ ํ•จ์ˆ˜ ๋„ฃ๋Š” ๋Œ€์‹  listening ์ด๋ฒคํŠธ ๋ถ™์—ฌ๋„ ๋จ
server.listen(8080); // ์„œ๋ฒ„ ์—ฐ๊ฒฐ
server.on("listening", () => { // on()์€ ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ํ•จ์ˆ˜. on(์ด๋ฒคํŠธ๋ช…, ์ฝœ๋ฐฑ)
  console.log("PORT 8080")
});
server.on("error", (error) => {
  console.error(error);
})
*/

 

 2. ๊ณผ์ œ basic-server.js ์ž‘์„ฑ

const http = require('http');

const PORT = 4999;
const ip = 'localhost';

const server = http.createServer((req, res) => {
  // res.end("Hello, Node JS Server");
  /* ↑ server ์‹คํ–‰์‹œ ๋ณด์—ฌ์ฃผ๋Š” ๋ฌธ๊ตฌ (๊ตฌํ˜„ ํ›„ ์‚ญ์ œํ•ด์•ผ ์ •์ƒ๋™์ž‘)
    ์„œ๋ฒ„๋ฅผ node server.js ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰์‹œ ๋ฌดํ•œ๋กœ๋”ฉ์ด ๋˜๋Š” ์ด์œ  : ์‘๋‹ต์ด ์—†๊ธฐ ๋•Œ๋ฌธ */

  // Preflight Request
  if (req.method === 'OPTIONS') {
    res.writeHead(200, defaultCorsHeader);
    res.end();
  }

  // POST 
  if (req.method === 'POST') {
    if (req.url === '/upper') {
      let data = '';
      req.on('data', chunk => { // ์š”์ฒญ์˜ data๋ฅผ stream ํ˜•์‹์œผ๋กœ ๋ฐ›์Œ
        data += chunk;
        
        // ํ™•์ธ์šฉ ์ฝ”๋“œ
        console.log("-------------------------------")
        console.log("UPPERCASE")

        console.log(chunk) // EX. Buffer๋กœ ์ถœ๋ ฅ <Buffer 79 63 65 66 66 6f 72 74>
        console.log(chunk + chunk) // chunk๋ฅผ +๋กœ ์—ฐ๊ฒฐ์‹œ ๋ฌธ์ž์—ด๋กœ ์ž๋™ ๋ณ€ํ™˜

        /*
          on()์€ ์ด๋ฒคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” ํ•จ์ˆ˜์ด๊ณ , ์œ„์˜ 'data'์™€ ์•„๋ž˜์˜ 'end'๋Š” ์ด๋ฒคํŠธ์ด๋‹ค.
          stream : ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ๊ฐ ์กฐ๊ฐ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ํฐ ๋ฐ์ดํ„ฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค.
          chunk : stream์—์„œ ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ž‘์€ ์กฐ๊ฐ.
          buffer : raw ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ˆ˜ํ•œ ์œ ํ˜•์˜ ๊ฐ์ฒด
          → ์ŠคํŠธ๋ฆผ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜ ์ „์†กํ•  ๋•Œ๋Š” chunk ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•œ๋‹ค. (๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์„ฑ๊ณผ ์„ฑ๋Šฅ ๋ฉด์—์„œ ์ด์ )
        */
        console.log("data", data)
        console.log("chunk", chunk.toString()) // Buffer๋Š” toString()์œผ๋กœ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜ ๊ฐ€๋Šฅ
        console.log("-------------------------------")

      });
      req.on('end', () => { // ์š”์ฒญ์˜ data๋ฅผ ๋‹ค ๋ฐ›์€ ํ›„ ์‹คํ–‰
        data = data.toUpperCase();
        res.writeHead(201, defaultCorsHeader);
        res.end(data);
      });
    } else if (req.url === '/lower') {
      let data = '';
      req.on('data', chunk => {
        data += chunk;

        // ํ™•์ธ์šฉ ์ฝ”๋“œ
        console.log("-------------------------------")
        console.log("LOWERCASE")
        console.log("data", data)
        console.log("chunk", chunk.toString()basic-server.js) 
        console.log("-------------------------------")

      });
      req.on('end', () => {
        data = data.toLowerCase();
        res.writeHead(201, defaultCorsHeader);
        res.end(data);
      });
    } else {
      res.writeHead(400, defaultCorsHeader);
      res.end();
    }
  }
});

server.listen(PORT, ip, () => {
  console.log(`http server listen on ${ip}:${PORT}`);
});

const defaultCorsHeader = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
  'Access-Control-Allow-Headers': 'Content-Type, Accept',
  'Access-Control-Max-Age': 10
};

 

 ๋‚ด์ผ ์˜ค์ „ ๋ผ์ด๋ธŒ์„ธ์…˜ ๋•Œ basic-server ๋ฆฌ๋ทฐ๋ฅผ ํ•˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ, ์•„๋งˆ ๋ฆฌ๋ทฐ๋ฅผ ํ•˜๋ฉด ์ด ๊ธ€์€ ์ˆ˜์ •๋ ์ˆ˜๋„..?!

 node.js๋ฅผ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š” ์ข‹์€ ๊ธฐํšŒ์˜€๊ณ , ์•ž์œผ๋กœ ๋” ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“œ๋Š” ๊ณผ์ œ์˜€๋‹ค :)


๐ŸŒ™  ์˜ค๋Š˜์˜ ํšŒ๊ณ 

 ์ด์ „ ์œ ๋‹›์—์„œ ๋ง›๋ณด๊ธฐ๋Š” ํ•œ ์  ์žˆ์ง€๋งŒ, ์‚ฌ์šฉํ•  ์ค„ ์ „ํ˜€ ๋ชจ๋ฅด๋Š” node.js๋กœ ์›น์„œ๋ฒ„๋ฅผ ๋งŒ๋“œ๋Š” ์‹ค์Šต์„ ํ–ˆ๋‹ค. ์ •๋ง ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๋Š”๋ฐ, ํ•™์Šต ์ž๋ฃŒ์™€ ๊ณต์‹ ๋ฌธ์„œ๋กœ๋Š” ์ถฉ๋ถ„ํžˆ ์ดํ•ด๊ฐ€ ๋˜์ง€ ์•Š์•„ ์–ด๋ ค์› ๋‹ค. ์ด์ „์— ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋ฐฐ์šฐ๋ฉฐ node.js๋„ ๋‹ค๋ค„๋ณด๊ณ  ์‹ถ์–ด์„œ ๊ด€๋ จ ์ฑ…์„ ๊ตฌ๋งคํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ, ๊ทธ ๋•Œ๋Š” ํŽผ์ณ๋ณด์ง€๋„ ๋ชปํ•œ ์ด ์ฑ…์ด ๋„์›€์ด ์ •๋ง ๋งŽ์ด ๋˜์—ˆ๋‹ค. ๐Ÿ˜‚ ์ด๋ ‡๊ฒŒ ์ €๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉฐ ์™„์„ฑ์€ ํ–ˆ์ง€๋งŒ, ์•„์ง๋„ ์ต์ˆ™์น˜ ์•Š์€ node.js

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

 ์˜ค๋Š˜๋„ ์ •๋ง ์—ด์‹ฌํžˆ ํ•ด์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋˜๋˜๋˜ ๋“œ๋Š” ํ•˜๋ฃจ์˜€๋‹ค. ๐Ÿซ 

๋ฐ˜์‘ํ˜•