TIL(42) Web Server

codedotΒ·2021λ…„ 9μ›” 12일
0

Web Server ✍🏻

ν΄λΌμ΄μ–ΈνŠΈ μš”μ²­μ— λŒ€ν•΄ 응닡할 수 μžˆλŠ” ν”„λ‘œκ·Έλž˜λ°μ„ λ§Œλ“€κΈ° μœ„ν•΄ node.jsλ₯Ό μ΄μš©ν•œλ‹€.

μ„œλ²„μƒμ„±

const http = require('http');

let server = http.createServer((requset, response) => {
	response.end('Hello world!');
});
server.listen(3000); // port번호
  • createServer ν•¨μˆ˜μ— 인자둜 λ“€μ–΄μ˜€λŠ” ν•¨μˆ˜μ˜ response 인자λ₯Ό μ‚¬μš©ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈμ˜ μš”μ²­μ— λŒ€ν•΄ μ•Œλ§žμ€ 응닡을 쀄 수 μžˆλ‹€.
  • response 객체의 end λ©”μ†Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ›ν•˜λŠ” 응닡을 쀄 수 μžˆλ‹€.
  • λͺ¨λ“  node μ›Ή μ„œλ²„ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ createServerλ₯Ό μ΄μš©ν•˜μ—¬ μ›Ή μ„œλ²„ 객체λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•œλ‹€.
  • 이 μ„œλ²„λ‘œ μ˜€λŠ” HTTP μš”μ²­λ§ˆλ‹€ createServer에 μ „λ‹¬λœ ν•¨μˆ˜κ°€ ν•œ λ²ˆμ”© ν˜ΈμΆœλœλ‹€.
  • HTTP μš”μ²­μ΄ μ„œλ²„μ— 였면 nodeκ°€ νŠΈλžœμž­μ…˜μ„ 닀루렀고 request와 response 객체λ₯Ό μ „λ‹¬ν•˜λ©° μš”μ²­ ν•Έλ“€λŸ¬ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

μš”μ²­

let body = [];
request.on('data', (chunk) => {
  body.push(chunk); //데이터가 λ“€μ–΄μ˜€λ©΄ μ½œλ°±ν•¨μˆ˜ μ‹€ν–‰
}).on('end', () => {
  body = Buffer.concat(body).toString(); //데이터가 λ“€μ–΄μ˜€λŠ” 게 λλ‚˜λ©΄ μ½œλ°±ν•¨μˆ˜ μ‹€ν–‰
  // μ—¬κΈ°μ„œ `body`에 전체 μš”μ²­ λ°”λ””κ°€ λ¬Έμžμ—΄λ‘œ λ‹΄κ²¨μžˆμŠ΅λ‹ˆλ‹€.
});
  • 슀트림의 'data'와 'end' μ΄λ²€νŠΈμ— 이벀트 λ¦¬μŠ€λ„ˆλ₯Ό λ“±λ‘ν•΄μ„œ 데이터λ₯Ό 받을 수 μžˆλ‹€.
  • 각 'data' μ΄λ²€νŠΈμ—μ„œ λ°œμƒμ‹œν‚¨ μ²­ν¬λŠ” Buffer이닀.
  • 이 청크가 λ¬Έμžμ—΄ λ°μ΄ν„°λΌλŠ” 것을 μ•Œκ³  μžˆλ‹€λ©΄ 이 데이터λ₯Ό 배열에 μˆ˜μ§‘ν•œ λ‹€μŒ 'end' μ΄λ²€νŠΈμ—μ„œ 이어 뢙인 λ‹€μŒ λ¬Έμžμ—΄λ‘œ λ§Œλ“œλŠ” 것이 κ°€μž₯ μ’‹λ‹€.
  • bodyλΌλŠ” λ³€μˆ˜μ— μš”μ²­ λ°”λ””κ°€ μ „λΆ€ λ¬Έμžμ—΄λ‘œ λ‹΄κ²¨μžˆλŠ” μƒνƒœμ—μ„œ 각 κ²½μš°μ— 따라 μ•„λž˜μ™€ 같이 쑰건문을 μž‘μ„±ν•˜μ—¬ 응닡 μΌ€μ΄μŠ€λ₯Ό λ‚˜λˆ„μ–΄ μ£Όμ—ˆλ‹€.
if (request.method === 'POST') { //POSTμš”μ²­ μ€‘μ—μ„œ
    if (request.url === '/lower') { //url이 /lower인 경우
      
    } else if (request.url === '/upper') {//url이 /upper인 경우
      
    } else { //κ·Έ μ™Έμ˜ μš”μ²­(μ—λŸ¬ 응닡)
      
    }
  }
  if (request.method === 'OPTIONS') { //CORS κ΄€λ ¨ 헀더λ₯Ό OPTIONS 응닡에 적용
 
  }

응닡바디

  • request의 λ©”μ†Œλ“œκ°€ OPTION인 κ²½μš°λŠ” ν΄λΌμ΄μ–ΈνŠΈκ°€ preflight requestλ₯Ό λ³΄λƒˆμ„ λ•Œ
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
};
  • preflight request 에 λŒ€ν•œ 응닡
response.statusCode = 200; //μ‘λ‹΅μ½”λ“œ
response.setHeader('Content-Type', 'application/json');
    // 주의: μœ„ 두 쀄은 λ‹€μŒ ν•œ μ€„λ‘œ λŒ€μ²΄ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
    // response.writeHead(200, {'Content-Type': 'application/json'})

const responseBody = { headers, method, url, body };

response.write(JSON.stringify(responseBody));
response.end();
    // 주의: μœ„ 두 쀄은 λ‹€μŒ ν•œ μ€„λ‘œ λŒ€μ²΄ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
    // response.end(JSON.stringify(responseBody))
--> μš”μ²­λ°”λ””λ₯Ό μ†Œλ¬Έμžλ‘œ λ°”κΏ”μ„œ μ‘λ‹΅ν•˜λŠ” κ²½μš°λŠ” μ•„λž˜μ™€ κ°™λ‹€.

req.on('end', () => {
        data = data.toLowerCase();
        res.writeHead(201, defaultCorsHeader); //(μ—λŸ¬μ½”λ“œ, 응닡헀더)
        res.end(data);
      });

HTTP μš”μ²­/응닡 처리 과정을 μžμ„Έν•˜κ²Œ μ„€λͺ…ν•˜κ³  μžˆλŠ” 곡식 λ¬Έμ„œ
λ§ν¬ν…μŠ€νŠΈ


cors(Cross Origin Resource Sharing)

  • cross originμ—μ„œ λ¦¬μ†ŒμŠ€(μ„œλ²„μžμ›)을 μš”μ²­ν•˜μ—¬ μ‚¬μš©ν•œλ‹€.
  • λ³΄μ•ˆ μƒμ˜ 이유둜, λΈŒλΌμš°μ €λ“€μ€ 슀크립트 λ‚΄μ—μ„œ μ΄ˆκΈ°ν™”λ˜λŠ” cross-origin HTTPμš”μ²­μ„ μ œν•œν•œλ‹€.
  • λΈŒλΌμš°μ €μ—μ„œ 크둜슀 도메인 μš”μ²­μ€ 기본적으둜 μ œν•œλœλ‹€.
  • μ›Ή μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 고도화λ₯Ό μœ„ν•΄ κ°œμ„  μš”μ²­
  • κ°œλ°œμžλ“€μ€ λΈŒλΌμš°μ € λ²€λ”μ‚¬λ“€μ—κ²Œ XML HTTP Requestκ°€ cross-domain μš”μ²­μ„ ν•  수 μžˆλ„λ‘ μš”μ²­
  • μ„œλ²„κ°€ ν—ˆμš©ν•œ λ²”μœ„λ‚΄μ—μ„œλŠ” μ‚¬μš© ν•  수 μžˆλ„λ‘ 함

Express.js (μ„œλ“œ νŒŒν‹° λͺ¨λ“ˆ)

  • node.jsμ—μ„œ 싀행될 μ„œλ²„ ν”„λ‘œκ·Έλž¨μ„ κ°„νŽΈν•˜κ²Œ λ§Œλ“€ 수 있게 ν•΄μ£ΌλŠ” ν”„λ ˆμž„μ›Œν¬
  • Expressλ₯Ό μ‚¬μš©ν•˜λ©΄, μ„œλ²„ ν”„λ‘œκ·Έλž¨μ΄ κ°–μΆ°μ•Όν•˜λŠ” κΈ°λŠ₯을 νŽΈν•˜κ²Œ κ΅¬ν˜„ν•  수 μžˆλ‹€.

μ„€μΉ˜ 방법

  • 터미널에 npm install express μž…λ ₯
profile
Loding...

0개의 λŒ“κΈ€