라우터 요청
서버는 우리가 입력하는 루트에 따라 기능이 달라짐
이는 / 뒤에 무엇을 입력하느냐가 기능을 좌우하게 됨
만약 /만 입력했을 때 유저가 데이터를 입력하는 페이지를 로드하고 이 데이터가 전송된 후 서버에 있는 파일에 저장하게 하려면 아래와 같은 코드처럼 작성할 수 있음
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require("http"); | |
const server = http.createServer((req, res) => { | |
const url = req.url; | |
if(url === '/') { | |
res.write('<html>'); | |
res.write('<head><title>Enter Message</title></head>'); | |
res.write('<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'); | |
res.write('</html>'); | |
return res.end(); | |
} | |
res.setHeader('Content-Type', 'text/html'); | |
res.write('<html>'); | |
res.write('<head><title>First Node.js</title></head>'); | |
res.write('<body><h1>Hello Node.js</h1></body>'); | |
res.write('</html>'); | |
res.end(); | |
}); | |
server.listen(3000); |
- 4 : /나 /example과 같이 URL을 새로운 상수에 저장
- 5 : if문을 사용하여 URL이 스트링이며 값이 /와 동일하면 작동되게 함
- 8 : action="/message"는 자동으로 생성된 요청이 전달될 URL을 추가해 주게 됨
name="message"는 입력 데이터를 요청 및 추가하고 할당된 이름을 통해 액세스 하게 됨 - 10 : 전체 함수의 작동을 중단하기 위하여 return을 붙여줌
만약, return을 사용하여 반환하지 않으면 if문 밖의 res.setHeader들부터 다시 실행하게 됨 - 이와 같이 코드를 작성하고 서버를 시작하고 localhost:3000/에 접속하게 되면 아래 화면과 같음

- 위의 화면에서 input에 무언가를 입력하고 Send 버튼을 누르면 아래 화면과 같이 바뀌게 됨

- 이와 같은 화면이 보이는 이유는 URL이 /message이고 이 URL은 위의 코드의 iif문에 반영되지 않아 if문 바깥의 코드가 실행되기 때문
요청 리디렉션
- 라우터 요청의 코드에서 /message로 POST 요청을 보내기만하고 어떠한 다른 작업도 하지 않았음
- 요청 리디렉션을 통해 POST 요청을 통해 다른 작업을 할 것임
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require("http"); | |
const fs = require('fs'); | |
const server = http.createServer((req, res) => { | |
const url = req.url; | |
const method = req.method; | |
if(url === '/') { | |
res.write('<html>'); | |
res.write('<head><title>Enter Message</title></head>'); | |
res.write('<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'); | |
res.write('</html>'); | |
return res.end(); | |
} | |
if (url === '/message' && method === 'POST') { | |
fs.writeFileSync('message.txt', 'Hello, This is Message'); | |
res.statusCode = 302; | |
res.setHeader('Location', '/'); | |
return res.end(); | |
} | |
res.setHeader('Content-Type', 'text/html'); | |
res.write('<html>'); | |
res.write('<head><title>First Node.js</title></head>'); | |
res.write('<body><h1>Hello Node.js</h1></body>'); | |
res.write('</html>'); | |
res.end(); | |
}); | |
server.listen(3000); |
- 3 : 파일 생성을 위해 파일 시스템 코어 모듈을 불러왔음
- 6 : request의 method에서 method를 파싱해 새로운 상수에 저장함
- 14 : URL이 /message이고 method가 POST일 때만 작동되게 조건문을 추가함
- 15 : writeFileSync를 사용하여 "Hello, This is Message"의 내용을 담고 있는 message.txt 파일을 생성하게 됨
- 16 : statusCode를 302로 설정함
- 17 : 위치를 지정해주었고, 위치가 /인 경우 현재 실행 중인 호스트를 자동으로 사용하게 됨
- 위 코드를 실행하게 되면 아래와 같은 화면이 뜨게 됨

- 이 화면에서 Send 버튼을 누르게 되면 아래와 같이 바뀌게 됨

- 여기서 네트워크 탭을 보면 message 요청을 전송했고, localhost로 리디렉트 되었고 상태코드가 302인 것을 볼 수 있음
- 이후 vsCode로 돌아와 보면 아래와 사진과 같이 message.txt가 추가된 것을 볼 수 있음

분석(데이터 스트림, 버퍼)
- 요청의 일부 중 데이터가 있는데, 데이터는 사용자가 입력하는 모든 것
- 데이터에 접근하는 방법은 따로 없음
- 대신 들어오는 요청이 데이터 스트림으로 보내지고, 이것은 JavaScript가 일반적으로 알고 있는 구조체이며 Node.js에서 많이 사용됨
- 우선, 데이터 스트림이 무엇인지 이해해야하고, 부가적으로 버퍼에 대해서도 이해해야 한다 !!!
데이터 스트림

- 데이터 스트림은 지속적인 프로세스
- 버퍼는 여러 개의 청크를 보유하고 파싱이 끝나기 전에 작업할 수 있도록 함
버퍼 사용법
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const http = require("http"); | |
const fs = require('fs'); | |
const server = http.createServer((req, res) => { | |
const url = req.url; | |
const method = req.method; | |
if(url === '/') { | |
res.write('<html>'); | |
res.write('<head><title>Enter Message</title></head>'); | |
res.write('<body><form action="/message" method="POST"><input type="text" name="message"><button type="submit">Send</button></form></body>'); | |
res.write('</html>'); | |
return res.end(); | |
} | |
if (url === '/message' && method === 'POST') { | |
const body = []; | |
req.on('data', (chunk) => { | |
console.log(chunk); | |
body.push(chunk); | |
}); | |
req.on('end', () => { | |
const parsedBody = Buffer.concat(body).toString(); | |
console.log(parsedBody); | |
}); | |
fs.writeFileSync('message.txt', 'This is Message'); | |
res.statusCode = 302; | |
res.setHeader('Location', '/'); | |
return res.end(); | |
} | |
res.setHeader('Content-Type', 'text/html'); | |
res.write('<html>'); | |
res.write('<head><title>First Node.js</title></head>'); | |
res.write('<body><h1>Hello Node.js</h1></body>'); | |
res.write('</html>'); | |
res.end(); | |
}); | |
server.listen(3000); |
- 15 : 요청 본문을 읽을 새로운 빈 배열 body를 생성해 주었음
- 16 :
POST 메시지를 받을 때 응답을 보내거나 파일에 쓰기 전에 요청 데이터를 받아야되기 때문에 req.을 입력하여 이벤트 리스너를 등록함
createServer는 대신 서버를 생성해 주는것처럼 on 메서드는 특정 이벤트를 들을 수 있도록 함
on 메서드의 첫번째 인자에는 "close", "data", "end', "error", "pause", "readable", "resume"이 있음
이 중, data 이벤트는 data를 입력하면 새 청크가 읽힐 준비가 될 때마다 data 이벤트가 발생하는 데에 버퍼가 도움을 줌
두 번째 인자에는 모든 data 이벤트에 실행될 함수를 넣어야 함
createServer와 비슷한 개념으로 들어오는 모든 요청에 실행될 함수를 정의한 것과 같이 여기에서는 들어오는 모든 데이터에 실행될 함수를 정의함
on(data)를 호출하고 리스너가 데이터 청크를 받도록 chunk를 입력해 주었음 - 17 : console.log를 통해 Node.js가 얼마나 실행하는지 또, 청크 안에 무엇이 있는지 확인
- 18 : 15번째 줄에서 만든 새로운 빈 배열 body에 새로운 요소로 청크를 푸시해서 비어있지 않은 배열을 만들어 줌
- 20 :
on 메서드의 첫 번째 인자인 end 이벤트는 들어오는 요청 데이터 혹은 들어오는 전반적인 요청을 분석한 후에 발생함
두 번째 인자로 정의하는 함수를 실행하는데, 이 함수는 읽어 들인 모든 청크에 기반할 수 있음 - 21:
parsedBody라는 새로운 상수를 생성하고 전역에서 사용 가능한 Buffer 객체를 사용해 concat(body)를 입력하고 toString()을 호출해 문자열로 전환하였음
이 때 만약, 요청의 본문이 텍스트가 아닌 다른 형식이었다면 다른 조치를 해주어야 함
이렇게 하면 새로운 버퍼가 생성되고 본문 안에 있던 모든 청크가 추가가 됨 - 22 : console.log를 통해 parsedBody가 무엇인지 확인함
- 이 코드를 실행하고 마찬가지로 localhost:3000에서 원하는 텍스트를 입력하고 콘솔창을 보게 되면 결과가 아래와 같음

- 사진의 첫 번째 콘솔의 출력값은 코드의 17번째 줄의 console.log(chunk)에 해당하고, 이것은 즉, 우리가 처리할 수 없는 청크임
- 사진의 두 번째 콘솔의 출력값은 코드의 22번째 줄의 console.log(parsedBody)에 해당하고, 이것은 즉, 우리가 처리할 수 있는 이러한 메시지를 산출하게 됨
- 또한, 입력 이름을 message라고 지었기 때문에 message=으로 시작하게 된 것
- 더 나아가, form이 모든 입력 데이터와 함께 자동으로 요청을 보내기때문에 요청 객체에 키-값 쌍으로 넣게되고, 입력에 주어지는 이름이 키이고, 사용자가 입력하는 것이 값에 해당함
'NodeJS' 카테고리의 다른 글
NodeJS의 작업 수행 방법 (1) | 2024.09.12 |
---|---|
이벤트 기반 코드 이해 & 블로킹, 논블로킹 코드 (0) | 2024.04.10 |
응답 전송 (0) | 2024.03.26 |
Node 서버 생성과 라이프사이클 및 이벤트 루프 (0) | 2024.03.26 |
웹 작동 방식 (0) | 2024.03.25 |