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
- localhost:3000 으로 접속이 가능함.
- 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하게 저장시 라이브러리 저장장소:
- /usr/local/bin/nodemon
- /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);