새로운 강의는 이제 https://memi.dev 에서 진행합니다.
memi가 Vue & Firebase로 직접 만든 새로운 사이트를 소개합니다.
NEMVV 3 웹서버 구동
이 강좌는 종료되었습니다.
새로운 강좌로 시작하세요~
모던웹(NEMV) 제작 강좌
express의 기본 웹서버 틀을 약간 수정하여 구동해봅니다.
소스는 https://github.com/fkkmemi/nemvv.git에서 확인 할 수 있습니다.
서버 구동 사전 체크
./bin/www : 유효성 체크
#!/usr/bin/env node
const fs = require('fs');
const pkg = require('../package');
if(!fs.existsSync('./cfg/cfg.js')) {
console.error('./cfg/cfg.js not exists');
process.exit(1);
}
var cfg = require('../cfg/cfg');
var gb = require('../system/global.js');
let chk = gb.f.cfg.check(cfg);
if(chk !== 'OK') {
console.error('./cfg/cfg.js file invalid ' + chk);
process.exit(1);
}
/**
* Module dependencies.
*/
var app = require('../app');
var debug = require('debug')(`${pkg.name}:server`);
기본적으로 cfg파일 유효성 체크를 했습니다.
var를 쓰는 이유는 최대한 express generated 된 코드는 건들지 않으려한 노력입니다.
서버 구동
./bin/www : 구동
if(cfg.web.http.use) {
var http = require('http');
var server = http.createServer(app).listen(cfg.web.http.port);
server.on('error', onError);
server.on('listening', onListening);
}
if(cfg.web.https.use) {
var https = require('https');
var o = {
key: fs.readFileSync(cfg.web.https.key),
cert: fs.readFileSync(cfg.web.https.cert),
ca: [fs.readFileSync(cfg.web.https.ca)]
}
var servers = https.createServer(o, app).listen(cfg.web.https.port);
servers.on('error', onError);
servers.on('listening', onListenings);
}
/**
* Event listener for HTTP server "error" event.
*/
function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}
var bind = `port ${cfg.web.http.port} or ${cfg.web.https.port}`
// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}
/**
* Event listener for HTTP server "listening" event.
*/
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('HTTP Listening on ' + bind);
}
/**
* Event listener for HTTPS server "listening" event.
*/
function onListenings() {
var addr = servers.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('HTTPS Listening on ' + bind);
}
http, https가 cfg파일대로 작동하는 것을 볼 수 있습니다.
별거 아닌 소스지만 혹시 ssl연결이 어려우신 분들이 참고하면 될 것 같습니다.
api, ssl등 전역처리
./app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
const mongoose = require('mongoose');
const cors = require('cors');
const cfg = require('./cfg/cfg');
const pg = require('./playGround');
if (!cfg) {
console.error('./cfg/cfg.js file not exists');
process.exit(1);
}
var app = express();
if(cfg.web.cors) {
app.use(cors({
exposedHeaders: ['WWW-Authenticate', 'Etag'],
}));
}
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json({ limit: '10mb' }));
app.use(bodyParser.urlencoded({ extended: false, limit: '10mb' }));
app.use(cookieParser());
app.use(function(req, res, next) {
if (cfg.web.cors) return next();
if (cfg.web.http.redirect && !req.secure) return res.redirect('https://' + req.headers.host + req.url);
next();
});
app.use(express.static(path.join(__dirname, 'fe', 'dist')));
app.use(express.static(path.join(__dirname, 'public')));
app.set('jwt-secret', cfg.web.secret_key);
app.use('/api', require('./routes/api'));
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.send({ success: false, msg: err.message });
});
mongoose.connect(cfg.db.url, (err) => {
if (err) return console.error(err);
console.log('mongoose connected');
pg.test.model();
});
module.exports = app;
- cors 처리 cors는 다른위치에서 xhr 요청을 했을 경우 응답을 해줄 수 있게 해주는 것입니다. 문제는 app.use(cors())만 해주면 헤더는 가려진다는 것입니다. 헤더에 특별한 데이터를 실어보낼때는 위와 같이 원하는 필드를 넣으면 보여지게 됩니다. eg) exposedHeaders: [‘WWW-Authenticate’, ‘Etag’]
xhr은 일반적으로 쓰이는 ajax같이 문서 내에서 전달되는 요청입니다. 응답시 console.log(req.xhr)을 찍어보면 확인 할 수 있습니다.
- ssl redirect 처리 res.redirect(‘https://’ + req.headers.host + req.url) http요청이 왔을때 https로 보냅니다.
서버를 https://xxx.com 로만 구성하면 좋지 않습니다. 그이유는 일반적으로 주소를 알려줄때 xxx.com이라고 알려줍니다. 브라우저마다 차이는 있지만 주소창에 xxx.com을 칠 경우 http://xxx.com으로 페이지가 없다고 뜰 수 있기 때문입니다. 그래서 http://xxx.com도 만들어 두고 https로 보내는 것이 좋다고 생각합니다.
댓글남기기