훈츠의 블로그 입니다.
안녕하세요. 훈츠입니다. 노드JS 정리해 봅니다. 생활코딩에서 1차로 노드 JS 완주하고 적는 완벽한 초심자 입장에서 적는거라, 초심자에게는 도움이 될것 같습니다. 어렵게 설명하고 싶어도, 아는게 없습니다. ㅎㅎ 그래도 전체적인 맥락 파악에는 도움이 되실것 같습니다. 노드 JS 가 무엇인지 알고 싶으시면, 생활코딩의 egoing 님 강좌 추천 드립니다.
글 목록
- 노드 JS 설치방법 [ 윈도우, 리눅스 ]
- 노드 JS 기본 시작 페이지 [ 원리 파악 ]
- 시작 페이지 전환
- URL 구조 및 주소 알아내기
- 콘솔 입력값 받아서 처리하기 [ process.argv ]
- Not found 404 오류 구현
- 노드 JS CRUD 샘플 프로그램 설명
- 파일 이용하여, 글목록 생성하기
- 노드 JS 동기와 비동기 그리고 콜백
- 노드 JS 패키지 매니저 PM2
- 노드 JS Form POST 방식으로 데이터 전송
- 노드 JS POST 방식으로 전송된 데이터 파일로 저장후, 리다이렉션
- 객체에 펑션 및 데이터를 담아서 모듈화해서 내보내고 사용하기
- 노드 JS POST 생성된 데이터 파일 update 후 전송
- 자바스크립트 - 객체의 활용
- 입력정보에 대한 보안 처리
- 출력정보에 대한 보안 처리
- API 개념
- 노드 JS Awesome 을 이용해서 쓸만한 모듈 찾아보기
- 코드 공유
노드 JS 설치방법 [ 윈도우, 리눅스 ]
윈도우에서 노드 js 설치법
공식사이트 : https://nodejs.org/ko/
1. 이곳에서 LTS 혹은 최신 버전을 다운 받으시고 설치하세요.
2. CMD 창에서 node-v 를 해서 설치 버전을 확인해보세요.
리눅스 설치 방법 [ build-essential, curl , yarn 도 설치]
1. root 계정으로 실행
2. sudo apt-get update
3. sudo apt-get install -y build-essential
4. sudo apt-get install curl
5. curl -sL https://deb.nodesource.com/setup_10.x | sudo - E bash -- (10버전 설치시)
5. curl -sL https://deb.nodesource.com/setup_12.x | sudo - E bash -- (12버전 설치시)
sudo - E bash -- (이부분은 안해도 설치했음.)
6. sudo apt-get install -y nodejs
노드 JS 기본 시작 페이지 [ 원리 파악 ]
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello, World!\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
|
cs |
해당 코드 리뷰
1. http 가져오기
2. hostname = localhost 세팅
3. port = 3000; 서버를 open 할 포트 번호
4. http.createServer ((req,res) =>
req : request 요청 입니다.
res : respond 응답 입니다.
res.statusCode = 200 // 200은 통신에 이상없다, 404 는 오류 처럼 약속이 있습니다.
res.setHeader( ) //HTML 문서 속성
res.end( ) // end 함수를 호출하면 그안에 인자값을 클라이언트에게 돌려 줍니다.
5. server.listen(port , hostname, () = >
port : 위에서 세팅한 3000번 포트로 요청이 들어오면 응답합니다.
hostname : ip address 를 세팅합니다.
6. node main.js 입력
아래 실행 화면을 확인 할수 있습니다.
서버 실행 화면
시작 페이지 전환 ( index.html )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
const http = require('http');
const fs = require('fs');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
//res.setHeader('Content-Type', 'text/plain');
var url =req.url;
if(req.url == '/'){
url = '/index.html'; //시작 페이지를 설정합니다.
}
res.writeHead(200);
res.end(fs.readFileSync(__dirname + url));
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
|
cs |
코드 리뷰
1. req.url URL 을 요청 합니다.
2. url 받아온 주소가 '/ ' 이거라면 url =/index.html 을 붙여줍니다.
3. writeHead(200) 통신 정상
4. res.end(fs.readFileSync(__dirname + url)); // 동기식 파일읽기 순서대로 읽어옵니다.
__dirname 은 따로 선언하지 않고 인자값으로 전달 합니다.
URL 구조 및 주소 알아내기
쿼리 스트링
Path 뒤에 페이지 전환을 위해 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
var http = require('http');
var fs = require('fs');
var url = require('url');
var qs = require('querystring');
var app = http.createServer(function(request,response){
var _url = request.url;
var queryData = url.parse(_url,true).query;
var pathname = url.parse(_url,true).pathname;
if(pathname === '/'){
if(queryData.id === undefined){ //home 이다.
fs.readdir('./data', function(err, filelist){
} else if(pathname === '/create'){
fs.readdir('./data', function(err, filelist){
//이하생략
} else if (pathname === '/update'){
fs.readdir('./data', function(err, filelist){
//이하생략
|
cs |
위 코드를 보시면 path 값을 가지고 화면을 구분 하는것을 알수 있습니다.
콘솔 입력값 받아서 처리하기 [ process.argv ]
main.js 를 실행할때, 콘솔로 값을 전달해 줄수 있습니다. 그 값은 process.argv [ ] 의 배열 값으로 들어옵니다. 다음 코드를 돌려보면 알수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
var args = process.argv
console.log(args);
console.log('A1');
if(args[2] == '1')
{console.log('B1-1');}
else
{console.log('B1-2');}
|
cs |
실행 화면을 확인해 보시면, node js 1 을 준 부분과 node js 2 를 준 실행 결과를 보면 우리가 console 로 부터 입력한 값에 의해 프로그램이 동작한 것을 확인 할수 있습니다.
Not found 404 오류 구현
HTTP 는 상태코드를 정의 하고, 표준을 따르도록 되어있습니다. 200 과 404 코드 정도는 알고 있는게 좋겠습니다.
HTTP 상태코드
모든 HTTP 응답 코드는 5개의 클래스(분류)로 구분됩니다. 상태 코드의 첫 번째 숫자는 응답의 클래스를 나태냅니다.
마지막 두 자리는 클래스나 분류 역할을 하지 않고, 첫자리에 대한 5가지 값들은 다음과 같습니다.
-
1xx (정보): 요청을 받았으며 프로세스를 계속한다
- 2xx (성공): 요청을 성공적으로 받았으며 인식했고 수용하였다
- 3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
- 4xx (클라이언트 오류): 요청의 문법이 잘못되었거나 요청을 처리할 수 없다
- 5xx (서버 오류): 서버가 명백히 유효한 요청에 대해 충족을 실패했다
404 (Not Found, 찾을 수 없음): 서버가 요청한 페이지(Resource)를 찾을 수 없다.
물론 표준을 따르면서 프로그램하는게 중요 하다고 생각합니다. 처음 부터 저런 규격을 모두 따르면 너무 복잡해 질것 같아서 해당 오류 처리 정도는 해주는게 맞다고 생각이 드네요.
https://ko.wikipedia.org/wiki/HTTP
노드 JS 에서는 해당 오류 처리는 다음과 같이 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
else if (pathname === '/delete_process'){
// 생략...
}
else {
response.writeHead(404); //서버가 요청한 페이지를 찾을수 없습니다.
response.end('not found')
}
});
app.listen(3001);
|
cs |
코드에서 처럼 맨 마지막에 보통 구성합니다.
노드 JS CRUD 구현 샘플프로그램
CRUD 란? Create : 생성 Read : 조회 Update : 변경 Delete : 삭제
이 부분을 이미 구현해 놓은 프로그램을 보면서 설명 드리도록 하겠습니다.
CRUD 를 노드 JS로 구현 하였습니다. FILE을 새로 생성하는 구조를 가지고 있습니다. 아래 부터 하나씩 설명드려보겠습니다.
이 샘플 프로그램은 FILE 을 생성하고, 읽고, 수정하고 삭제하는 프로그램 입니다. 추후 파일이 아닌 데이터 베이스에 그대로 적용하면 될것 같네요. 데이터 베이스 자체만 학습을 해봤는데 웹 앱 어플리케이션에는 아직 적용을 안해봤습니다.
파일 이용하여, 글목록 생성하기
파일을 이용하여, 목록을 생성하기 이전에 파일 자체를 생성하고, 읽고, 수정 삭제 하는 방법에 대해 알아보겠습니다.
파일 읽기 fs.readFile
사용법
1. fs 을 불러 옵니다.
2. fs.readFile 함수를 호출 합니다. 매개변수로 다음 세가지가 있습니다.
(file을 읽어올 위치 및 파일 이름, 형식, 펑션 ) 형식을 지정 안하면 내용이 표기가 안됩니다.
3. 함수(err , 값) // err는 에러에 관한 내용이, 값에는 우리가 요청한 파일의 값이 리턴이 되어 들어옵니다.
파일 목록 읽기 fs.readdir
사용법
1. fs 을 불러 옵니다.
2. fs.readdir 함수를 호출 합니다. 매개변수로 다음 두가지가 있습니다.
(folder 를 읽어올 경로 , 펑션 ) 폴더의 경로만 잘입력 하면 됩니다.
3. 펑션의 인자 값 (err, 값) // err 는 error 값이 들어오고, 두번째 값이 요청한 값이 들어옵니다.
글 목록 생성하기
앞서 file을 읽는 방법과 폴더에 file 목록을 읽어오는 방법을 알아 보았습니다. 이제 우리는 이 두함수를 이용해서 생성 즉 Create 를 구현 할수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
//Hoons Blog---https://rain2002kr.tistory.com------------------------------------------------------------------코드///
var http = require('http');
var fs = require('fs');
var url = require('url');
function templateHTML(title,list,body){
return `
<!doctype html>
<html>
<head>
<title>WEB1 -${title}</title>
<meta charset="utf-8">
</head>
<body>
<h1><a href="/">WEB</a></h1>
${list}
${body}
</body>
</html>
`;
}
function templateList(filelist){
var list = `<ul>`;
var i = 0;
while(i < filelist.length){
list = list + `<li><a href="/?id=${filelist[i]}">${filelist[i]}</a></li>`;
i = i+ 1;
}
list = list +`</ul>`;
return list;
}
var app = http.createServer(function(request,response){
var _url = request.url;
var queryData = url.parse(_url,true).query;
var pathname = url.parse(_url,true).pathname;
if(pathname === '/'){
if(queryData.id === undefined){ //home 이다.
//디렉토리에 파일면 읽어오기
fs.readdir('./data', function(err, filelist){
var title = 'Welcome';
var descriton = 'Hello, Node.js';
var list = templateList(filelist)
var template = templateHTML(title,list,`<h2>${title}</h2>${descriton}`);
response.writeHead(200); //웹서버와 브라우저간에 통신하기 위한 간결한 약속 200 성공 문자
response.end(template);
});
}else{
fs.readdir('./data', function(err, filelist){
//파일 내용 읽어오기
fs.readFile(`data/${queryData.id}`,'utf8',function(err,descriton){
var title = queryData.id;
var list = templateList(filelist)
var template = templateHTML(title,list,`<h2>${title}</h2>${descriton}`);
response.writeHead(200); //웹서버와 브라우저간에 통신하기 위한 간결한 약속 200 성공 문자
response.end(template);
});
});
}
} else {
response.writeHead(404);
response.end('not found')
}
});
app.listen(3001);
|
cs |
그렇게 어렵지 않은 내용이라 전체 코드 붙여 넣었습니다. 코드 구현은 샘플 프로그램 영상에 있으니 다시 한번 보셔도 좋을것 같습니다.
노드 JS 동기와 비동기 그리고 콜백
동기처리는 한번에 한가지 일을 처리하고 다음으로 넘어가고, 비동기 처리는 한번에 여러가지 일을 처리 합니다.
비동기 처리는 효율적이지만, 처리 하기가 조금 복잡 합니다. 왜냐하면 콜백이라는 개념을 알아야 하기 때문입니다.
하지만 예제코드에 익숙해지만 콜백에 대한 개념도 잡을수 있습니다.
동기 코드 예제
비동기 코드
콜백 개념
위와 같이 fileAsync 함수가 완료 된후, callback 함수를 호출합니다. 콜백 함수의 동작 원리를 보여주기위한 예시 입니다. 위 readFile 비동기 함수에 함수 값이 콜백으로 나오면 리턴값을 출력 할수 있는 원리와 같습니다.
노드 JS 패키지 매니저 PM2 설치
패키지 매니저인 PM2 를 설치하면 노드 JS 애플리케이션을 실행하고, 정지하고 상태 관리를 할수 있습니다. 그리고 추가적으로 현재 제가 사용하고 있는 IDE 인 VS code 에서 window power shell 을 설치해서 VS code 터미널 창에서 제어 할수 있도록 설치해 보도록 하겠습니다.
VS Code 에 Window PowerShell 설치
1. VS Code 에서 터미널 창을 열고 ( CTRL + SHIFT + P ) 입력 합니다.
2. shell 이라고 프롬프트 상단에 치고 설치를 시작 합니다.
3. 나머지 사항은 디폴트 항목으로 엔터 하고 넘어 갑니다.
PM2 패키지 매니저 설치
1. npm install -g pm2
PM2 간단 사용 설명
c:/프로젝트경로>
pm2 start main.js --watch
pm2 monit 실행 중인 리스트를 모니터 할수있습니다.
pm2 list 실행 중인 리스트를 볼수 있습니다.
pm2 log 실행 중인 상태의 로그를 볼수 있습니다.
pm2 kill 실행 중인 리스트를 모두 끝냅니다.
노드 JS Form POST 방식으로 데이터 전송
다음 HTTP 규약을 보면 요청에 Body가 있는 경우는 POST 혹은 PUT으로 전송합니다. 클라이언트 사이드에서 서버 사이드로 body 가 있는 데이터를 전송할 예정이므로 POST 방식을 이용합니다.
사용 설명서
1. form 태그 action ="url 정보를 넘겨줍니다"
2. method = "POST " 방식을 사용합니다.
3. input type="submit" 을 사용합니다.
노드 JS POST 방식으로 전송된 데이터 받아서 파일로 저장후, 리다이렉션
앞서 POST 방식으로 전송된 데이터를 받아서 파일로 저장 하는 방법에 대해 알아보도록 하겠습니다.
POST 방식으로 많은 양의 데이터를 전송할때, 끊길수 있기 때문에 다음과 같은 방식을 제공 합니다.
조각조각 데이터를 수신할때마다 콜백 함수를 호출합니다. 이때 데이터의 끝을 알리는 데이터가 들어오면 클라이언트 에 값을 돌려줍니다.
데이터 수신 :
req.on('data' ,function(data){ body = +data ; } 수신 시작
req.on('end', function( ) { qs.parse(body) .....; } 수신 끝처리
위 코드는 데이터를 수신 하는것을 담았습니다. 이제 다음 코드뷰에서 수신된 데이터를 파일로 저장하도록 하겠습니다.
파일로 생성 및 저장 후 리다이렉션
fs.wirteFile 이용
사용설명서
1. fs.writeFile 을 이용하여, 파일을 만들고 데이터를 씁니다.
2. writeHead( 302, 앞서 HTTP 프로토콜 규약중 하나인 리다이렉션 입니다.
3xx (리다이렉션): 요청 완료를 위해 추가 작업 조치가 필요하다
요구한 데이터가 변경된 URL에 있음을 명시. 301과 비슷하지만 새 URL은 임시 저장 장소로 해석됩니다.
객체에 펑션 및 데이터를 담고 모듈화 해서 내보내서 사용하기
일반적인 코드에서도 자주 쓰는 코드에 대해서 우린 Function을 만들어 내용을 분리 합니다. 자바스크립트에서는 펑션을 변수에 담을수가 있습니다. 고로 오브젝트를 만들고 그안에 펑션을 담아서 내보낼수가 있습니다. 형식은 다음과 같습니다.
아래 코드에서 사용될, 리스트를 읽어오고 title과 dscription 값을 쓰는 영역을 템플릿화 해서 내보냈습니다.
위와 같이 사용할 자바스크립트 코드에서 require 를 통해서 불러옵니다.
노드 JS POST 생성된 데이터 파일 update 후 전송
생성된 파일로 부터 내용을 읽은 다음 다시 POST 로 전송하는 업데이트에 대해 알아보도록 하겠습니다.
생성된 파일로 부터 내용을 읽는 부분 말고는 위에서 CREATE 하는 부분과 동일하므로 해당 부분만 설명 하도록 하겠습니다. 위에 설명드린 펑션중 fs.readdir 파일에 디렉토리와 파일에 내용을 읽어온후, POST로 보내고 create_process와 마찬가지로 전송받은 내용으로 업데이트 하면 됩니다.
파일 목록 읽기 fs.readdir
파일 읽기 fs.readFile
위 form 에 update 항목을 보시면 create와 완전히 동일합니다. 단지 fs.readdir 과 fs.readFile을 통해서 리스트와 그안에 내용만 읽어와서 수정해야할 내용에 쓰는 부분만 추가 되었습니다.
위 코드는 서버 데이터를 전송받아 정보수신이 끝나면 파일에 정보를 입력후, 리다이렉션 하는 펑션입니다. Create와 완전 동일합니다.
노드 JS POST 파일 삭제 구현 하기 (fs.unlink 함수)
앞서 CRUD 에 해당하는 내용을 모두 구현 하였는데요. 이번에는 이미 구성된 파일을 삭제하는 방법에 대해 알아보도록 하겠습니다. delete는 폼에 내용이 없기 때문에 바로 'POST' 방식으로 전송된 path와 쿼리 스트링을 가지고 바로 파일을 삭제 하면됩니다. 이때 사용되는 함수는 fs.unlink 라는 함수 입니다.
사용 설명
1. queryData 에서 id를 가져옵니다.
2. fs.unlink 함수에서 받아온 id로 파일을 삭제 합니다.
3. respone.writeHead(302, 통해서 리다이렉션 합니다.
자바스크립트 - 객체 활용
노드JS 에서 자바스크립트를 사용하기 때문에 자바스크립트 이야기를 빼놓을순 없을것 같습니다. 배열은 모두 익숙하실것 같은데, 객체에서 for in 문에서 값을 뽑는 방법에 대해 설명 드리도록 하겠습니다.
객체를 출력하는 방법은 다음 을 참조 하시면 됩니다.
함수를 배열에 담을수도 있습니다.
입력정보에 대한 보안 처리 path.parse('./temp.js').base
서버에서 데이터베이스를 핸들링하기 위해서는 데이터베이스의 id와 password가 있어야 합니다. 이때 만약 pw.js 라는곳에 값을 입력해놓았는데, 해커가 path경로를 입력해서 password를 해킹하는수도 있고, data 폴더가 아닌 다른 영역에 접근해서 값이 바뀌어서 사이트가 망가질수도 있습니다. 이러한 심각한 손상을 막기 위해서 입력된 데이터뒤에 .base를 붙여서 상위로 움직이지 못하게 하는 방법 입니다.
처음에는 무슨말인지 이해가 잘가지 않았는데 다음 사진을 보시면 이해가 되실겁니다.
1> queryData.id 즉 base 값이 아닌 전체 정보 입력이 가능했을때 입니다.
출력 결과에 패스워드가 나온거 보이시죠?
자 이번에는 (QueryData.id).base 를 입력하고 접속해 보았습니다.
이번에는 파일을 읽을때, 쿼리데이터에 .base 값 즉 'password.js' 로 접속 하다보니 개발자가 의도한 폴더외에는 접근 자체를 할수 없는것을 볼수 있습니다.
보안이 얼마나 중요한 부분인지 새삼 느끼는 항목 이었네요.
출력정보에 대한 보안 처리 ( SanitizeHtml )
입력 정보 뿐만 아니라, 출력정보 역시 상당히 중요한 부분입니다. 입력을 받아서 출력하는 부분이라고 하더라도 다음과 같이 입력된 정보에 <script> 보안 문제를 야기하는 코드들 </script> 이렇게 들어있다면 문제가 되겠지요.
그래서 이러한 출력 정보를 세탁 할수 있는 SanitizeHTML 이라는 라이브러리가 있습니다. 사용법은 아주 손쉽습니다.
물론 다른 기능을 사용하기 위해서는 학습이 필요해 보이겠지만 이정도만 적용해도 괜찮을듯 보입니다. 용감한...발언 인듯 하지만,,,아는게 없어서..ㅠㅠ
SanitizeHTML 사이트 : https://www.npmjs.com/package/sanitize-html
간단 사용법
1. npm install sanitize-html
2. 다음 코드를 이용해서, 출력 부분에 넣어 줍니다.
3. 코드 적용 예시 (출력 부분)
API 개념
조작 장치 인터페이스 이며, 개발사 홈페이지에 가면 DOC 안에 아주 정리가 잘되어있습니다. 사실 아직 까지 저도 API 보고 하라고 하면 헤매긴 하지만요. ㅜㅜ
노드 Awesome JS 을 이용해서 쓸만한 모듈 찾아보기
해당 사이트에 가보시면 사용하시는 프레임워크를 선택 할수 있는 화면이 나옵니다. 그럼 그안에서 개발자들이 많이 사용하고 추천하는 라이브러리들이 나오는데 이곳에서 괜찮은 모듈을 찾아서 적용해 보는것도 아주 좋을듯 하네요.
사이트 : https://awesomejs.dev/
코드 공유
감사합니다. 오류나 오탈자가 있으면 알려주세요. ^^
'노드JS [Express]' 카테고리의 다른 글
[쿠키 와 인증] 노드JS Cookie 인증 정리글 (2) | 2020.06.29 |
---|---|
[Node JS Express and React 배우기] yarn dev 를 이용한 서버와 리액트 프론트 동시 실행방법. (0) | 2020.06.26 |
[노드 JS Express and React] yarn dev 를 이용한 서버와 리액트 프론트 동시실행 (0) | 2020.06.26 |
[REST API ] Rest API 쉽게 정리 합니다. (0) | 2020.06.19 |
[Node js express 배우기] 노드 JS Express 정리 하면서 배우자. (2) | 2020.06.16 |