mulll

Node js 기초 본문

node.js

Node js 기초

dongha 2022. 12. 3. 02:58

 

node.js

 

NPM Project 시작

npm → 필요한 라이브러리(패키지)를 임포트할 수 있음

  • 노드 시작
npm init

→ package.json 파일 생성됨 → package에 대한 메타 정보가 들어있음

 

  • 패키지 설치
npm install express --save

# --save: 외부에서 dependencies 정보를 통해 express를 받을 수 있도록 package.json에 있는
# dependencies에 express를 추가해줌
  • express: node.js의 대표적인 웹 서버 기능을 지원하는 패키지
  • node_modules 라는 디렉토리가 생성되는데, express 및 다른 패키지가 필요로 하는 라이브러리들이 존재하게됨.

 

 

Express 기반 웹서버 구동

  • express로 기본적인 서버 열기
# app.js에 메인 코드 작성
vi app.js
var express = require('express')
var app = express()
app.listen(3000, function(){
  console.log("start! express server on port 3000");
});
  • 3000번 포트에 실행
  • express를 불러와 실행

 

 

  • app.js 실행
node app.js

 

 

  • node는 동기/비동기 함수로 구성되어있음
var express = require('express')
var app = express()

app.listen(3000, function(){
  console.log("start! express server on port 3000");
});

console.log("end of server code ...")
  • 위 코드의 실행 결과
(base)  donghakim@dongui-MacBookPro  ~/__ESW/node_basic  node app.js
end of server code ...
start! express server on port 3000
  • 결과: app.listen은 비동기로 동작하는데,,, app.listen 코드 실행 부분을 기다리지 않고 다음 console.log(”end ~~”)를 실행 → 결국 동기 함수가 모두 다 실행되고난 후 비동기 함수가 순차적으로 실행됨
  • console.log는 동기로 동작(순서대로 동작)

 

 

  • nodemon: 자동으로 코드의 변화를 탐지하고 node를 자동으로 재실행해주는 패키지
  • nodemon 설치
npm install nodemon --save
  • express때와 마찬가지로 package.json에 dependencies에 추가됨

 

  • nodemon을 사용하려면 다음과 같이 app.js를 실행
nodemon app.js

 

  • global 하게 npm install
sudo npm install nodemon -g
  • -g 옵션 추가
  • 실제 global하게 저장시 라이브러리 저장장소:
  1. /usr/local/bin/nodemon
  1. /usr/local/lib/node_modules/nodemon/bin/nodemon.js

URL Routing 처리

 

GET localhost:3000/ url routing example

app.get("/", function(req, res){
	res.send("hello node.js");
});

→ 위 url으로 get 요청 시 res.send 내부의 내용이 html 타입으로 리턴됨.

 

  • 이미 존재하는 html 파일을 리턴해서 보여주고 싶을 경우

먼저 현재 디렉토리에서 public 디렉토리를 생성 후 그 내에 main.html을 대충 생성하여 그 main.html을 보여주고싶다고 가정.

 

app.get("/", function(req, res){
	res.sendFile("/Users/donghakim/__ESW/node_basic/public/main.html");
});

→ absolute path 대신 relative path를 주고싶을 때

app.get("/", function(req, res){
	res.sendFile(__dirname + "/public/main.html");
// 또는 res.sendFile('public/main.html' , { root : __dirname});
});

__dirname은 현재 작업중인 디렉토리의 절대주소를 나타내므로 상대경로를 다음과 같이 두가지 방법으로 지정할 수 있다.

 

Static Directory 설정

public 폴더 내에 들어있는 js파일, css파일, 이미지 파일과 같은 static파일을 불러오고 지정하기 위해

express에게 public 디렉토리를 static 디렉토리로 지정하라고 명령

app.use(express.static("public"))

 

 

 

POST 요청 처리

app.post("/email_post", function(req, res){
	res.send("email posting success");
});

 

  • post로부터온 request body를 분석하기 위해

npm install body-parser --save

 

  • 코드 윗줄에 아래와같이 body-parser 불러오기

 

var bodyParser = require('body-parser')

 

  • Express에게 bodyParser를 사용하겠다고 알림
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
	extended:true
}))

 

 

  • post 요청으로부터 얻은 request body 내용 출력
app.post("/email_post", function(req, res){
	// res.send("email posting success");
	res.send(req.body)
});

json type으로 send

 

View Engine을 통한 응답처리

 

ejs: View Engine

설치

npm install ejs -—save

view engine을 ejs로 사용하겠다고 express에게 알림

app.set('view engine', 'ejs')

 

  • email.ejs 작성

ejs파일은 기본적으로 views 디렉토리를 만들고 그 디렉토리 내부에 존재해야함

<h1>Welcome ejs!! <%= email %> </h1>
  • form 태그로 이메일을 작성하고 post로 요청하면 email.ejs를 보여줄 수 있게끔 app.js 수정

(res.sendFile 대신 res.render사용)

app.post("/email_post", function(req, res){
	res.render('email.ejs', {
		'email': req.body.email
	})
});

 

 

JSON 활용한 Ajax처리

다음과 같이 form.html 작성

<body>
    <form action = "/email_post" method = "post">
        email address : <input type="text" name = "email"> <br/>
        <input type="submit">
    </form>

    <button class = "ajaxsend">ajaxsend</button>
    <div class="result"></div>

    <script>
        document.querySelector('.ajaxsend').addEventListener('click', function(){
            var inputData = document.forms[0].elements[0].value
            console.log(inputData)
            sendAjax('http://localhost:3000/ajax_send_email', inputData)
        })

        function sendAjax(url, data){
            var data = {
                'email': data
            };
            data = JSON.stringify(data);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', url);
            xhr.setRequestHeader('Content-Type', "application/json");
            xhr.send(data);
            xhr.addEventListener('load', function(){
                console.log(xhr.responseText); // 서버로부터 응답 받은 값을 log로 찍어줌
                var result = JSON.parse(xhr.responseText);
                if(result.result !== 'ok') return;
                document.querySelector('.result').innerHTML = result.email;
            });
        }
    </script>
</body>

 

 

app.js 추가

app.post('/ajax_send_email', (req, res) => {
	console.log(req.body.email);
	var responseData = {
		'result': 'ok',
		'email': req.body.email
	};
	res.json(responseData);
});

MySQL 연동 설정

  • mysql 키고 db 생성
mysql -u root -p

create database my_db;
  • mysql과 node를 연동하기 위해 mysql 패키지 설치
npm install mysql --save
  • app.js에서 mysql 불러오기
  • express와 mysql 연동
var mysql = require('mysql')

var connection = mysql.createConnection({
	host: 'localhost',
	port: 3306,
	user: 'root',
	password: '1234',
	database: 'my_db'
});

connection.connect();
  • 에러뜰경우 → mysql 버전 호환문제일 가능성 큼 아래와 같이 mysql에 입력

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '1234';

 

 

MySQL 연동 구현

app.post('/ajax_send_email', (req, res) => {
	var responseData = {};
	var email = req.body.email;

	var queary = connection.query('select * from member where email = "' + email + '"', (err, rows) => {
		if(err) throw err;
		console.log(rows)
		if(rows[0]){
			responseData.result = 'ok';
			responseData.email = email;
		}
		else {
			responseData.result = "none";
			responseData.email = "";
		}
		res.json(responseData)
	});
});
  • form.html에서 입력한 email주소가 db에 저장되어 있을 시 ok 및 email 리턴

 

Routing 모듈화 - 1

 

quest: localhost:3000/main/~ 으로 들어오는 요청을 모듈화해서 하나의 main.js 파일이 관리할 수 있도록함.

 

router 폴더 생성

./router/main.js 작성

var express = require('express');
var router = express.Router();
var path = require('path')

router.get("/", (req, res) => {
    console.log("main.js is loaded...")
	res.sendFile(path.join(__dirname, '../public/main.html'));
});


module.exports = router;

 

app.js에 라우팅 정보 추가

var main = require('./router/main')
...
app.use('/main', main)

/main/~으로 오는 요청은 main.js로 보내겠다.

 

Routing 모듈화 - 2 (DB 연결부분)

/email/~ 이하 요청을 /email로 routing 하기 위해서 form.html에서 요청 url 변경

  • /email_post → /email/post: form 태그의 button 누를 시
  • /ajax_send_email → /email/ajax: ajax로 비동기로 버튼을 눌러 데이터 전송 시
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>email-form</title>
</head>
<body>
    <form action = "/email/post" method = "post">
        email address : <input type="text" name = "email"> <br/>
        <input type="submit">
    </form>

    <button class = "ajaxsend">ajaxsend</button>
    <div class="result"></div>

    <script>
        document.querySelector('.ajaxsend').addEventListener('click', () => {
            var inputData = document.forms[0].elements[0].value
            console.log(inputData)
            sendAjax('http://localhost:3000/email/ajax', inputData)
        })

        function sendAjax(url, data){
            var data = {
                'email': data
            };
            data = JSON.stringify(data);
            var xhr = new XMLHttpRequest();
            xhr.open('POST', url);
            xhr.setRequestHeader('Content-Type', "application/json");
            xhr.send(data);
            xhr.addEventListener('load', () => {
                console.log(xhr.responseText); // 서버로부터 응답 받은 값을 log로 찍어줌
                var result = JSON.parse(xhr.responseText);
                if(result.result !== 'ok') return;
                document.querySelector('.result').innerHTML = result.email;
            });
        }
    </script>
</body>
</html>

 

main.js와 같은 디렉토리(/router)에 email.js 생성

var express = require('express');
var router = express.Router();
var path = require('path');
var mysql = require('mysql');

var connection = mysql.createConnection({
	host: 'localhost',
	port: 3306,
	user: 'root',
	password: '1234',
	database: 'my_db'
});

connection.connect();


router.post("/post", (req, res) => {
	res.render('email.ejs', { // render는 기본적으로 views 디렉토리부터 path가 시작됨.
		'email': req.body.email
	})
});

router.post('/ajax', (req, res) => {
	var responseData = {};
	var email = req.body.email;

	var queary = connection.query('select * from member where email = "' + email + '"', (err, rows) => {
		if(err) throw err;
		console.log(rows)
		if(rows[0]){
			responseData.result = 'ok';
			responseData.email = email;
		}
		else {
			responseData.result = "none";
			responseData.email = "";
		}
		res.json(responseData)
	});
});


module.exports = router; // 추가하는 것 필수

 

  • app.js에 app.post(”/post/~”) 부분 다 삭제하고 app.js에 다음 추가
var email = require('./router/email'); // load email.js
app.use('/email', email); // add router(/email) to express

 

 

 

Routing - 3 (Refactoring)

  • localhost:3000/~ 요청부터 감싸서 컨트롤러를 대규모로 관리하는 middleware 구성

 

  • /router/index.js 작성(미들웨어)
// middleware


var express = require('express');
var app = express();
var router = express.Router();
var path = require('path');
var main = require('./main');
var email = require('./email');



router.get("/", function(req, res){
	res.sendFile(path.join(__dirname, '../public/main.html'));
});

router.use('/main', main);
router.use('/email', email); // add router(/email) to express

module.exports = router;

 

  • app.js 수정
var express = require('express')
var app = express()
var bodyParser = require('body-parser');
var index = require('./router/index')
app.listen(3000, () => {
	console.log("start! express server on port 3000");
});

app.use(express.static("public"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
	extended:true
}));

app.set('view engine', 'ejs'); // view engine을 ejs로 사용하겠다고 express에 알림

app.use("/", index);

Comments