์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 |
- Kuring
- ํจ์คํธ์บ ํผ์ค
- XCTest
- realm
- designpattern
- reactorkit
- Lv2
- Swfit
- raywenderlich
- tableView
- RxSwift
- Xcode
- CollectionView
- combine
- UIKit
- visionOS
- SnapKit
- SwiftUI
- TCA
- swift
- rxcocoa
- BOJ
- ๋ฐฑ์ค
- arkit
- ํ๋ก๊ทธ๋๋จธ์ค
- MVVM
- ios
- node.js
- BFS
- Flutter
- Today
- Total
lgvv98
[Node.js] #6 ์ต์คํ๋ ์ค ์น ์๋ฒ ๋ง๋ค๊ธฐ ๋ณธ๋ฌธ
์ต์คํ๋ ์ค ์น ์๋ฒ ๋ง๋ค๊ธฐ
#4์์ ์๋ฒ ๋ง๋ค๊ธฐ ๋ถํธํ์๊ฑฐ๋ค. ์ด์ ์ข ์ฌ์์ง๋๊น ์์๋ณด์.
# ์ต์คํ๋ ์ค ํ๋ก์ ํธ ์์ํ๊ธฐ
์ฐ์ learn-express๋ฅผ ๋ง๋ค์ด๋ณด์.
npm init -y
์๋์ฒ๋ผ ์์ ํ์.
{
"name": "learn-express",
"version": "0.0.1",
"description": "์ต์คํ๋ ์ค๋ฅผ ๋ฐฐ์๋ณด์",
"main": "app.js",
"scripts": {
"start": "nodemon app"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"nodemon": "^3.0.1"
}
}
๊ทธ ๋ค์์๋
npm i express
npm i -D nodemon
script๊ฐ ์์ฑ๋๋๋ฐ ์ด ๋ถ๋ถ์ ๋ฐ๋์ start ์์ฑ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. nodemon app์ ํ๋ฉด app.js๋ฅผ nodemon์ผ๋ก ์คํํ๋ค๋ ์คํํ๋ค๋ ๋ป์ด๋ค.
์ฝ์์ rs๋ฅผ ์ ๋ ฅํด์ ์๋์ผ๋ก ์ฌ์์๋ ๊ฐ๋ฅ.
nodemon์ ๊ฐ๋ฐ์ฉ์ผ๋ก๋ง ์ฌ์ฉํ ๊ฒ์ ๊ถ์ฅ.
์๋ฒ์ ์ญํ ์ ํ app.js์ ์์ฑ
const express = require('express');
const app = express();
app.set('port', process.env.PORT || 3000); // env์ ํฌํธ๊ฐ ์์ผ๋ฉด ์ฌ์ฉํ๊ณ ์๋๋ฉด 3000๋ฒ
// app.set(ํค, ๊ฐ) ํตํด์ ๋ฐ์ดํฐ ์ ์ฅ
// app.get(ํค, ๊ฐ)์ผ๋ก ๋์ค์ ์ฝ์
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋น ํฌํธ์์ ๋๊ธฐ์ค');
});
์์๋ฅผ html ํ์ด์ง๋ฅผ ๋ฃ์ด์ ๋ฐ๊ฟ๋ณด์.
// index.html
<html>
<head>
<meta charset="UTF-8" />
<title>์ต์คํ๋ ์ค ์๋ฒ</title>
</head>
<body>
<h1>Express</h1>
<p>๋ฐฐ์๋ด
์๋ค.</p>
</body>
</html>
// app.js
const express = require('express');
const path = require('path');
const app = express();
app.set('port', process.env.PORT || 3000);
app.get('/', (req, res) => {
// res.send('Hello World');
res.sendFile(path.join(__dirname, 'index.html'));
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋น ํฌํธ์์ ๋๊ธฐ์ค');
});
์๋กฑํ๋ค!
# ์์ฃผ ์ฌ์ฉํ๋ ๋ฏธ๋ค์จ์ด
๋ฏธ๋ค์จ์ด๋ ์ต์คํ๋ ์ค์ ํต์ฌ์ด๋ค.
๋ฏธ๋ค์จ์ด๋ app.use์ ํจ๊ป ์ฌ์ฉ๋๋ค.
// app.js
const express = require('express');
const path = require('path');
const app = express();
app.set('port', process.env.PORT || 3000);
// โ
app.use('/', (req, res, next) => {
console.log('๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋๋ค.');
next();
});
// โ
app.get('/', (req, res, next) => {
console.log('GET ์์ฒญ์์๋ง ์คํ๋๋ค.');
next();
}, (req, res) => {
throw new Error('์๋ฌ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ๋๋ค.');
});
// โ
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
app.use์์๋ req, res, nextํจ์๋ฅผ ๋ฃ์ผ๋ฉด ๋๋ค. ๋ฏธ๋ค์จ์ด๋ ์์์๋ถํฐ ์๋๋ก ์์๋๋ก ์คํ๋๋ฉด์ ์์ฒญ๊ณผ ์๋ต ์ฌ์ด์ ํน๋ณํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์์. ์ด๋ฒ์๋ next๋ผ๋ ์๋ฒ์งธ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋๋ฐ, ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ๋ ํจ์. next๋ฅผ ์คํํ์ง ์์ผ๋ฉด ๋ค์ ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋์ง ์์.
์ฃผ์๋ฅผ ์ฒซ๋ฒ์งธ ์ธ์๋ก ๋ฃ์ด์ฃผ์ง ์๋๋ค๋ฉด ๋ฏธ๋ค์จ์ด๋ ๋ชจ๋ ์์ฒญ์์ ์คํ๋๊ณ , ์ฃผ์๋ฅผ ๋ฃ๋๋ค๋ฉด ํด๋นํ๋ ์์ฒญ์์๋ง ์คํ๋๋ค๊ณ ๋ด.
app.use(๋ฏธ๋ค์จ์ด): ๋ชจ๋ ์์ฒญ์์ ๋ฏธ๋ค์จ์ด ์คํ
app.use('/abc', ๋ฏธ๋ค์จ์ด): abc๋ก ์์ํ๋ ์์ฒญ์์ ๋ฏธ๋ค์จ์ด ์คํ
app.post('/abc', ๋ฏธ๋ค์จ์ด): abc๋ก ์์ํ๋ POST ์์ฒญ์์ ๋ฏธ๋ค์จ์ด ์คํ
app.use๋ app.get ๊ฐ์ ๋ผ์ฐํฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ๋ฌ๊ฐ๋ฅผ ์ฅ์ฐฉํ ์ ์๋ค.
app.get ๋ผ์ฐํฐ์ ๋ฏธ๋ค์จ์ด๊ฐ ๋ ๊ฐ ์ฐ๊ฒฐ๋์ด ์์. ๋ค๋ง ์ด๋๋ next๋ฅผ ํธ์ถํด์ผ ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ ์ ์๋ค.
์๋ฌ์ฒ๋ฆฌ!! ๋งค๊ฐ๋ณ์๋ ๋ค ๊ฐ๋ค. ๋ชจ๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ๋งค๊ฐ๋ณ์๊ฐ ๋ฐ๋์ ๋ค ๊ฐ์ฌ์ผ ํ๋ค.
res.status ๋ฉ์๋๋ก HTTP ์ํ ์ฝ๋๋ฅผ ์ง์ ํ ์ ์๋ฐ. ๊ธฐ๋ณธ๊ฐ์ 200์ด๋ฉฐ ์ค๋ฌด์์๋ ์ง์ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋๊ฒ ์ข๋ค. ์๋ฌ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ ํน๋ณํ ๊ฒฝ์ฐ ์๋๋ฉด ๊ฐ์ฅ ์๋์ ์ใ ํ๋๋ก ํ๋ค.
๋ฏธ๋ค์จ์ด๋ฅผ ํตํด ์์ฒญ๊ณผ ์๋ต์ ๋ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๊ณ , ์ค๋ฌด์ ์์ฃผ ์ฌ์ฉํ๋ ํจํค์ง๋ค์ ์ค์นํด๋ด ์๋ค.
npm i morgan cookie-parser express-session dotenv
dotenv ํจํค์ง๋ .env ํ์ผ์ ์ฝ์ด์ precess.env๋ก ๋ง๋ญ๋๋ค. process.env.COOKIE_SECRET์ cookiesecret ๊ฐ์ด ํ ๋น๋๋ค.
ํค=๊ฐ ํ์์ผ๋ก ์ถ๊ฐํ๋ฉด ๋๋ค. process.env๋ฅผ ๋ณ๋์ ํ์ผ๋ก ๊ด๋ฆฌํ๋๊ฑด ๋ณด์๊ณผ ์ค์ ์ ํธ์์ฑ
๋น๋ฐ ํค๋ค์ ์์ค ์ฝ๋์ ๊ทธ๋๋ก ์ ์ด๋๋ฉด ์์ค ์ฝ๋๊ฐ ์ ์ถ๋์์ ๋๋ ํค๋ ๊ฐ์ด ์ ์ถ ๋ฐ๋ผ์ .env ๊ฐ์ ๋ณ๋์ ํ์ผ์ ๋น๋ฐํค๋ฅผ ์ ์ด๋๊ณ ๊ด๋ฆฌํจ ์์ค์ฝ๋๊ฐ ์ ์ถ๋๋๋ผ๋ .envํ์ผ๋ง ์ ๊ด๋ฆฌํ๋ฉด ์งํฌ ์ ์๋ค.
// .env
COOKIE_SECRET=cookiesecret
์๋ ์ฝ๋๋ฅผ ์์ฑํด๋ณด์
// app.js
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config(); // โ
์ค์
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
const multer = require('multer');
const fs = require('fs');
try {
fs.readdirSync('uploads');
} catch (error) {
console.error('uploads ํด๋๊ฐ ์์ด uploads ํด๋๋ฅผ ์์ฑํฉ๋๋ค.');
fs.mkdirSync('uploads');
}
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads/');
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
limits: { fileSize: 5 * 1024 * 1024 },
});
app.get('/upload', (req, res) => {
res.sendFile(path.join(__dirname, 'multipart.html'));
});
app.post('/upload', upload.single('image'), (req, res) => {
console.log(req.file);
res.send('ok');
});
app.get('/', (req, res, next) => {
console.log('GET / ์์ฒญ์์๋ง ์คํ๋ฉ๋๋ค.');
next();
}, (req, res) => {
throw new Error('์๋ฌ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ๋๋ค.')
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
# morgan
morgan ์ฐ๊ฒฐ ํ, ๊ธฐ์กด ๋ก๊ทธ ์ธ์ ์ถ๊ฐ์ ์ธ ๋ก๊ทธ๋ฅผ ๋ณผ ์ ์์.
3000๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค
๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋๋ค.
GET / ์์ฒญ์์๋ง ์คํ๋ฉ๋๋ค.
Error: ์๋ฌ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ๋๋ค.
// ์๋ฌ ์คํ ํธ๋ ์ด์ค ์๋ต
GET / 500 6.332 ms - 50
๋งจ ์๋ ๋ก๊ทธ๋ morgan ๋ฏธ๋ค์จ์ด์์ ๋์ค๋ ๊ฒ์ด๋ค. ์์ฒญ๊ณผ ์๋ต์ ๋ํ ์ ๋ณด๋ฅผ ์ฝ์์ ๊ธฐ๋ก
morgan ๋ฏธ๋ค์จ์ด๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉ
app.use(morgan('dev'));
์ธ์๋ก dev ์ธ์ combined, common, short, tiny ๋ฑ์ ๋ฃ์ ์ ์๋ค.
๊ฐ๋ฐํ๊ฒฝ์ dev, ๋ฐฐํฌํ๊ฒฝ์ combined
# static
static ๋ฏธ๋ค์จ์ด๋ ์ ์ ์ธ ํ์ผ๋ค์ ์ ๊ณตํ๋ ๋ผ์ฐํฐ ์ญํ ์ ํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณต๋๊ธฐ์ ๋ฐ๋ก ์ค์นํ ํ์ ์์ด express ๊ฐ์ฒด ์์์ ๊บผ๋ด ์ฅ์ฐฉํ๋ฉด ๋๋ค.
app.use('์์ฒญ ์ ๋ณด', express.static('์ค์ ๊ฒฝ๋ก'));
app.use('/', express.static(path.join(__dirname, 'public'));
ํจ์์ ์ธ์๋ก ์ ์ ํ์ผ๋ค์ด ๋ด๊ฒจ ์๋ ํด๋๋ฅผ ์ง์ ํ๋ฉด ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด public/stylesheet/style.css๋ http://localhost:3000/stylesheets/style.css๋ก ์ ๊ทผํ ์ ์์.
์ค์ ์๋ฒ์ ํด๋ ๊ฒฝ๋ก์๋ public์ด ๋ค์ด ์์ง๋ง ์์ฒญ ์ฃผ์์๋ ์๋๋ฐ ์์ฒญ ๊ฒฝ๋ก๊ฐ ๋ค๋ฅด๋ฏ๋ก ์ธ๋ถ์ธ์ด ์๋ฒ์ ๊ตฌ์กฐ๋ฅผ ์ฝ๊ฒ ํ์ ํ ์ ์์.
๋ํ, fs.readFile์ ํ์ผ์ ์ง์ ์ฝ์ด์ ์ ์กํ ํ์๊ฐ ์์. ๋ง์ฝ ์์ฒญ ๊ฒฝ๋ก์ ํด๋นํ๋ ํ์ผ์ด ์์ผ๋ฉด ์์์ ๋ด๋ถ์ ์ผ๋ก next๋ฅผ ํธ์ถ ํ์ผ ๋ฐ๊ฒฌํ๋ฉด ๋ฏธ๋ค์จ์ด๋ ์คํ์๋ผ ์๋ต์ผ๋ก ํ์ผ ๋ณด๋ด๊ณ next๋ฅผ ํธ์ถํ์ง ์์.
# body-parser
์์ฒญ์ ๋ณธ๋ฌธ์ ์๋ ๋ฐ์ดํฐ๋ฅผ ํด์ํด์ req.body ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ค๋ค.
๋ณดํต ํผ ๋ฐ์ดํฐ๋ AJAX ์์ฒญ์๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌ. ๋จ, ๋ฉํฐํํธ(์ด๋ฏธ์ง, ๋์์, ํ์ผ) ๋ฐ์ดํฐ ์ฒ๋ฆฌํ์ง ๋ชปํจ.
์ด ๊ฒฝ์ฐ์๋ ๋ค์ ๋์ค๋ multer ๋ชจ๋์ ์ฌ์ฉํ๋ฉด ๋๋ค.
body-parser๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋๋ค.
app.use(express.join());
app.use(express.urlencoded({ extended: false }));
์๋๋ ์์ฒญ ๋ฐ์ดํฐ์ ์ข ๋ฅ๋ค.
const bodyParser = require('body-parser');
app.use(bodyParser.raw());
app.use(bodyParser.text());
์์ฒญ ๋ฐ์ดํฐ ์ข ๋ฅ์ ๋ํด ์ดํด๋ณด์.
JSON์ JSONํ์์ ๋ฐ๋ผ URL-encoded๋ ์ฃผ์ ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ์ ํผ ์ ์ก์ URL-encoded ๋ฐฉ์์ ์ฃผ๋ก ์ฌ์ฉ
urlencoded ๋ฉ์๋๋ฅผ ๋ณด๋ฉด { extended: false }๋ผ๋ ์ต์ ์ด ๋ค์ด ์๋ค.
์ด ์ต์ ์ด false์ด๋ฉด ๋ ธ๋์ querystring ๋ชจ๋์ ์ฌ์ฉํด ์ฟผ๋ฆฌ์คํธ๋ง์ ํด์ํ๊ณ , qs ๋ชจ๋์ npm์ ํตํด ์ฌ์ฉํ๋ ๋ชจ๋
POST์ PUT์์ฒญ์์ ๋ณธ๋ฌธ ๋ฐ์ผ๋ฉด req.on('data') req.end('data) ํ๋๊ฑฐ ๊ธฐ์ต๋จ?
๋ฐ๋ ํ์ ์ฌ์ฉํ๋ฉด ์ํด๋ ๋ผ
# cookie-parser
์์ฒญ์ ๋๋ด๋ ์ฟ ๋ฆฌ๋ฅผ ํด์ํด req.cookies ๊ฐ์ฒด๋ก ๋ง๋ ๋ค.
app.use(cookieParser(๋น๋ฐ ํค));
์๋ฅผ๋ค์ด name=lgvv ์ฟ ํค๋ฅผ ๋ณด๋๋ค๋ฉด, { name: 'lgvv' }๊ฐ ๋๋ค. ์ ํจ ๊ธฐ๊ฐ์ด ์ง๋ ์ฟ ํค๋ ์์์ ๊ฑธ๋ฌ๋ธ๋ค.
์ฒซ๋ฒ์งธ์ธ์๋ก ๋น๋ฐํค๋ฅผ ๋ฃ์ด์ค ์ ์๋ค.
res.cookie('name', 'lgvv', {
expires: new Date(Date.now() + 90000),
httpOnly: true,
secure: true,
});
res.clearCookie('name', 'lgvv', { httpOnly: true, secure: true });
์ฟ ํค๋ฅผ ์ง์ฐ๋ ค๋ฉด ํค ๊ฐ ์ธ์ ์ต์ ๋ง์ ๋ ์ ํํ ์ผ์นํด์ผ ๋ง๋๋ ์ง๋ค. ๋จ expires๋ maxAge ์ต์ ์ ์ผ์นํ ํ์ ์์.
์ต์ ์ค์๋ signed๋ผ๋ ์ต์ ์ด ์๋๋ฐ, ์ด๋ฅผ true๋ก ์ค์ ํ๋ฉด ์ฟ ํค ๋ค์ ์๋ช ์ด ๋ถ๋๋ค. ๋ด ์๋ฒ๊ฐ ์ฟ ํค๋ฅผ ๋ง๋ค์๋ค๋ ๊ฒ์ ๊ฒ์ฆํ ์ ์์ผ๋ฏ๋ก ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์๋ช ์ต์ ์ ์ผ๋๋ ๊ฒ์ด ์ข๋ค. ์๋ช ์ ์ํ ๋น๋ฐ ํค๋ cookieParser ๋ฏธ๋ค์จ์ด์ ์ธ์๋ก ๋ฃ์ process.env.COOKIE_SECRET์ด ๋ฉ๋๋ค.
# express-session
์ธ์ ๊ด๋ฆฌ์ฉ ๋ฏธ๋ค์จ์ด. ๋ก๊ทธ์ธ ๋ฑ์ ์ด์ ๋ก ์ธ์ ์ ๊ตฌํํ๊ฑฐ๋ ํน์ ์ฌ์ฉ์๋ฅผ ์ํ ๋ฐ์ดํฐ ์์์ ์ผ๋ก ์ ์ฅํด๋ ๋ ๋งค์ฐ ์ ์ฉ. ์ธ์ ์ ์ฌ์ฉ์๋ณ๋ก req.session ๊ฐ์ฒด ์์ ์ ์ง๋๋ค.
app.use(session({
resave: false, // โ
์์ฒญ์ด ๋ค์ด์ฌ ๋ ์ธ์
์ ์์ ์ฌํญ ์๊ธฐ์ง ์๋๋ผ๋ ์ธ์
์ ๋ค์ ์ ์ฅํ ์ง ์ค์
saveUninitialized: false, // โ
์ธ์
์ ์ ์ฅํ ๋ด์ญ์ด ์๋๋ผ๋ ์ธ์
์ ์ฌ์์ํ ์ง ์ค์
secret: process.env.COOKIE_SECRET, // โ
์ธ์
๊ด๋ฆฌ์ ํด๋ผ์ด์ธํธ์ ์ฟ ํค
cookie: { // โ
์ผ๋ฐ์ ์ธ ์ฟ ํค ์ต์
์ ์ ๊ณต
httpOnly: true, // โ
ํด๋ผ์ด์ธํธ์์ ์ฟ ํค ํ์ธ ๋ชปํ๊ฒ
secure: false, // โ
https์ ์ฉ์ฌ๋ถ
},
name: 'session-cookie', // โ
env ๊ฐ
}));
์์ ์๋ ์์ง๋ง store๋ผ๋ ์ต์ ์ด ์๋๋ฐ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ด๊ธฐํ๋์ด ์ธ์ ์ด ๋ชจ๋ ์ฌ๋ผ์ง๋๋ผ๋ store์ ๋ฐ๋ฒ ๋ฅผ ์ฐ๊ฒฐํด ์ธ์ ์ ์ ์งํ๋๊ฒ์ด ์ข๋ค.
๋ณดํต ๋ ๋์ค๊ฐ ์ฐ์.
store.session.name = 'lgvv'; // ์ธ์
๋ฑ๋ก
req.sessionID; // ์ธ์
์์ด๋ ํ์ธ
req.session.destroy(); // ์ธ์
๋ชจ๋ ์ ๊ฑฐ
# ๋ฏธ๋ค์จ์ด์ ํน์ฑ ํ์ฉํ๊ธฐ
๋ฏธ๋ค์จ์ด๋ฅผ ์ง์ ๋ง๋ค์ด๋ณด๊ธฐ๋ ํ๊ณ , ๋ค๋ฅธ ์ด๋ง์ด ๋ง๋ ๋ฏธ๋ค์จ์ด ํจํค์ง๋ฅผ ์ค์นํด ์ฅ์ฐฉํด๋ณด๊ธฐ๋ ํจ.
์ด๋ฒ์๋ ๊ทธ ํน์ฑ์ ์ ๋ฆฌํด ๋ณผ ์์ .
app.use((req, res, next) => {
console.log('๋ชจ๋ ์์ฒญ์ ๋ค ์คํ๋๋ค.');
next();
});
๋ฏธ๋ค์จ์ด๋ req, res, next๋ฅผ ๊ฐ๋ ํจ์๋ก์จ app.use๋ app.get, app.post ๋ฑ์ผ๋ก ์ฅ์ฐฉํ๋ค. ํน์ ํ ์ฃผ์์ ์์ฒญ์๋ง ๋ฏธ๋ค์จ์ด๊ฐ ์คํ๋๊ฒ ํ๋ ค๋ฉด ์ฒซ๋ฒ์งธ ์ธ์๋ก ์ฃผ์๋ฅผ ๋ฃ์ผ๋ฉด ๋๋ค.
app.use(
morgan('dev');
express.static('/', path.join(__dirname, 'public');
express.json();
express.urlencoded({ extended: false }),
cookeParser(precess.env.COOKIE_SECRET),
);
์์ ๊ฐ์ด ์ฌ๋ฌ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฅ์ฐฉํ ์ ์์ผ๋ฉฐ, ๋ค์ ๋ฏธ๋ค์จ์ด๋ก ๋์ด๊ฐ๋ ค๋ฉด ํจ์๋ฅผ ํธ์ถํด์ผ ํ๋ค.
์ ๋ฏธ๋ค์จ์ด๋ค์ ๋ด๋ถ์ ์ผ๋ก next()๋ฅผ ํธ์ถํ๊ณ ์์ผ๋ฏ๋ก ์ฐ๋ฌ์ ์ธ ์ ์๋ค.
next๋ฅผ ํธ์ถํ์ง ์๋ ๋ฏธ๋ค์จ์ด๋ res.send๋ res.sendFile ๋ฑ์ ๋ฉ์๋๋ก ์๋ต์ผ ๋ณด๋ด์ผ ํ๋ค.
express.static๊ณผ ๊ฐ์ ๋ฏธ๋ค์จ์ด๋ ์ ์ ํ์ผ์ ์ ๊ณตํ ๋ next ๋์ res.sendFile ๋ฉ์๋๋ก ์๋ต์ ๋ณด๋ ๋๋ค.
๋ฐ๋ผ์ ์ ์ ํ์ผ์ ์ ๊ณตํ๋ ๊ฒฝ์ฐ expree.json์ด๋ express.urlencoded, cookieParser ๋ฏธ๋ค์จ์ด๋ ์คํ๋์ง ์๋๋ค.
๋ฏธ๋ค์จ์ด ์ฅ์ฐฉ ์์์ ๋ฐ๋ผ ์ด๋ค ๋ฏธ๋ค์จ์ด๋ ์คํ๋์ง ์์์๋ ์๋ค.
next์ ์ธ์๋ฅผ ๋ฃ์์๋ ์์
next('route')๋ผ๋ ์ธ์๋ฅผ ๋ฃ์ผ๋ฉฐ ๋ค์ ๋ผ์ฐํฐ์ ๋ฏธ๋ค์จ์ด๋ก ๋ฐ๋ก ์ด๋ํ๊ณ , ๊ทธ ์ธ์ ์ธ์๋ฅผ ๋ฃ๋๋ค๋ฉด ๋ฐ๋ก ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ์ด๋.
next(error) ๋ค์ ์๋ฌ ํธ๋ค๋ฌ๋ก ๋ณด๋
(err, req, res, enxt) => { }
๋ฏธ๋ค์จ์ด ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ๋ ์์. ์ธ์ ์ ์ฌ์ฉํ๋ค๋ฉด req.session ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด๋ ๋์ง๋ง, ์ธ์ ์ด ์ ์ง๋๋ ๋์์ ๋ฐ์ดํฐ๋ ๊ณ์ ์ ์ง๋๋ค๋ ๋จ์ ์ด ์๋ค.
๋ง์ฝ ์์ฒญ์ด ๋๋ ๋ ๊น์ง๋ง ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๊ณ ์ถ๋ค๋ฉด res.locals ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด๋๋ฉด ๋๋ค.
app.use((req, res, next) => {
res.locals.data = '๋ฐ์ดํฐ ๋ฃ๊ธฐ';
next();
}, (req, res, next) => {
console.log(res.locals.data); // ๋ฐ์ดํฐ ๋ฐ๊ธฐ
next();
});
์์ฒญ์ด ์ฒ๋ฆฌ๋๋ ๋์ res.locals ๊ฐ์ฒด๋ฅผ ํตํด ๋ฏธ๋ค์จ์ด ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์์.
์๋ก์ด ์์ฒญ์ด ๋ค์ด์ค๋ฉด res.locals๋ ์ด๊ธฐํ ๋๋ค.
app.set๊ณผ์ res.locals์ ์ฐจ์ด.
app.get, req.app.get์ผ๋ก ์ด๋์๋ ์ง ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์. ํ์ง๋ง app.set์ ํ์ง ์๊ณ ์ res.locals ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ ๋ฏธ๋ค์จ์ด๋ก ์ ๋ฌํ๋ ์ด์ ๊ฐ ์์. app.set์ ์ต์คํ๋ ์ค์์ ์ ์ญ์ ์ผ๋ก ์ฌ์ฉ๋๋ฏ๋ก ํ๋์ ์์ฒญ ์์์๋ง ์ ์ง๋์ด์ผ ํ๋ ๊ฐ์ ๋ฃ๊ธฐ์๋ ๋ถ์ ์ ํ๋ค. app.set์ ์ฑ ์ ์ฒด์ ์ค์ ์ ๊ณต์ ํ ๋ ์ฌ์ฉํ๋ฉด ๋๋ค.
res.locals ๊ฐ์ฒด๋ ํ๋์ ์์ฒญ ์์์๋ง ์ ์ง๋๋ฏ๋ก res.locals ๊ฐ์ฒด๋ฅผ ํตํด ์์ฒญ์ ์ข ์๋๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ์ข๋ค.
๋ฏธ๋ค์จ์ด ์์ ๋ฏธ๋ค์จ์ด๋ฅผ ๋ฃ๋ ์ ์ฉํ ๋ฐฉ์
app.use(morgan('dev'));
// or
app.use((req, res, next) => {
morgan('dev')(req, res, next);
});
์ด ํจํด์ด ์ ์ฉํ๊ฑด ๊ธฐ์กด ๋ฏธ๋ค์จ์ด ๊ธฐ๋ฅ ํ์ฅ ์๋ฅผ ๋ค์ด ๋ถ๊ธฐ ์ฒ๋ฆฌ๋ ๊ฐ๋ฅ
์๋์ฝ๋ ๋ณด์
app.use((req, rex, next) => {
if (precess.env.NODE_ENV === 'production') {
morgan('combined')(req, res, next);
} else {
morgan('dev')(req, res, next);
}
});
์กฐ๊ฑด๋ฌธ์ ๋ฐ๋ผ ๋ถ๊ธฐ๋ ๊ฐ๋ฅ
# multer
์ด๊ฑด ๋ค์ ์ด๋ ค์ด๋ฐ ์ด๋ฏธ์ง๋ ์์ ๋ฑ์ ๋น๋กฏํ ๋ฉํฐํํธ ์ด๋ฏธ์ง ํ์ผ์ ์ ๋ก๋ํ ๋ ์ฌ์ฉํ๋ ๋ฏธ๋ค์จ์ด
<form id="form" action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image1" />
<input type="file" name="image2" />
<input type="text" name="title" />
<button type="submit">์
๋ก๋</button>
</form>
์ด๊ฑด ์ง์ ํ์ฑํ๊ธฐ ๊น๋ค๋ก์์ multer ๋ฏธ๋ค์จ์ด ์ฌ์ฉํ๋ฉด ํธ๋ฆฌํจ.
npm i multer
multer ํจํค์ง ์์๋ ์ฌ๋ฌ ์ข ๋ฅ์ ๋ฏธ๋ค์จ์ด๊ฐ ๋ค์ด์๋ค.
const multer = require('multer');
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) { // โ
์ด๋ค ์ด๋ฆ์ผ๋ก ์ด๋์ ์ ์ฅํ ์ง
done(null, 'uploads/'); // โ
์๋ฌ๊ฐ ์๋ค๋ฉด error๋ฅผ ๋ฃ๊ธฐ, ๋๋ฒ์งธ ์ธ์๋ ์ค์ ๊ฒฝ๋ก๋ ํ์ผ์ด๋ฆ
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext); // โ
[ํ์ผ๋ช
+ ํ์ฌ์๊ฐ.ํ์ฅ์]
},
}),
limits: { fileSize: 5 * 1024 * 1024 }, // โ
5MB๋ก ์ฉ๋์ ํ
});
์ ์ฝ๋ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๋ ค๋ฉด upload ํด๋๊ฐ ๋ฐ๋์ ์กด์ฌํด์ผ ํ๋ค.
์๋ค๋ฉด ์ง์ ๋ง๋ค์ด์ฃผ๊ฑฐ๋ fs๋ชจ๋ ์ฌ์ฉํด์ ์๋ฒ ์์ฑํ ๋ ์์ฑํด์ผ ํ๋ค.
const fs = require('fs');
try {
fs.readdirSync('uploads');
} catch (error) {
console.error('uploads ํด๋๊ฐ ์์ด ํด๋๋ฅผ ์์ฑ');
fs.mkdirSync('uploads');
}
์ค์ ์ด ๋๋๋ฉด upload ๋ณ์๊ฐ ์๊ธฐ๋๋ฐ, ์ฌ๊ธฐ์ ๋ค์ํ ์ข ๋ฅ์ ๋ฏธ๋ค์จ์ด๊ฐ ์๋ค.
๋จผ์ ํ์ผ์ ํ๋๋ง ์ ๋ก๋ํ๋ ๊ฒฝ์ฐ ์ฑ๊ธ ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๋ค.
app.post('/upload', upload.single('image'), (req, res) => {
console.log(req.file, req.body);
res.send('ok');
});
single ๋ฏธ๋ค์จ์ด๋ฅผ ๋ผ์ฐํฐ ๋ฏธ๋ค์จ์ด ์์ ๋ฃ์ด๋๋ฉด multer ์ค์ ์ ๋ฐ๋ผ ํ์ผ ์ ๋ก๋ ํ req.file ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
req.file ๊ฐ์ฒด๋ ์๋์ฒ๋ผ ์๊น
๋ฉํฐํํธํผ์์
์ด๋ฒ์ ๋ฏธ๋ค์จ์ด๋ single ๋์ array๋ฅผ ์ฌ์ฉํด๋ณด์
app.post('/upload', upload.array('many'), (req, res) => {
console.log(req.file, req.body);
res.send('ok');
});
์ ๋ก๋ ๊ฒฐ๊ณผ๋ req.file๋์ req.files ๋ฐฐ์ด์ ๋ค์ด ์๋ค.
ํ์ผ์ ์ฌ๋ฌ ๊ฐ ์ ๋ก๋ํ์ง๋ง input ํ๊ทธ๋ ํผ ๋ฐ์ดํฐ์ ํค๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ์๋ fileds ๋ฏธ๋ค์จ์ด๋ฅผ ์ฌ์ฉํ๋ค
<form id="form" action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image1" />
<input type="file" name="image2" />
<input type="text" name="title" />
<button type="submit">์
๋ก๋</button>
</form>
fields ๋ฏธ๋ค์จ์ด์ ์ธ์๋ก input ํ๊ทธ์ name์ ๊ฐ๊ฐ ์ ๋๋ค.
app.post('/upload',
upload.fields([{ name: 'image1' }, { name: 'image2' }]), (req, res) => {
console.log(req.file, req.body);
res.send('ok');
});
์ ๋ก๋ ๊ฒฐ๊ณผ๋ req.files.image1, req.files.image2๋ก ๋ฐ๋ก ๋ค์ด์์.
ํน์ํ ๊ฒฝ์ฐ์ง๋ง ํ์ผ ์์ด๋ ๋ฉํฐํํธ ํ์์ผ๋ก ์ฌ๋ฆฌ๊ธฐ๋ ํจ
app.post('/upload', upload.none(), (req, res) => {
console.log(req.body);
res.send('ok');
});
ํ์ผ ์ ๋ก๋ํ์ง ์์์ ๋ฐ๋๋ง ์กด์ฌํ๋ค.
์ค์ ๋ก multer์์ ์ค์ตํ๋ ค๋ฉด app.js์์
// multipart.html
<form id="form" action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image1" />
<input type="file" name="image2" />
<input type="text" name="title" />
<button type="submit">์
๋ก๋</button>
</form>
// app.js
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config();
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
const multer = require('multer');
const fs = require('fs');
try {
fs.readdirSync('uploads');
} catch (error) {
console.error('uploads ํด๋๊ฐ ์์ด uploads ํด๋๋ฅผ ์์ฑํฉ๋๋ค.');
fs.mkdirSync('uploads');
}
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads/');
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
done(null, path.basename(file.originalname, ext) + Date.now() + ext);
},
}),
limits: { fileSize: 5 * 1024 * 1024 },
});
app.get('/upload', (req, res) => {
res.sendFile(path.join(__dirname, 'multipart.html'));
});
app.post('/upload', upload.single('image'), (req, res) => {
console.log(req.file);
res.send('ok');
});
app.get('/', (req, res, next) => {
console.log('GET / ์์ฒญ์์๋ง ์คํ๋ฉ๋๋ค.');
next();
}, (req, res) => {
throw new Error('์๋ฌ๋ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด๋ก ๊ฐ๋๋ค.')
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
# Router ๊ฐ์ฒด๋ก ๋ผ์ฐํ ๋ถ๋ฆฌํ๊ธฐ
์์ฒญ ๋ฉ์๋์ ์ฃผ์๋ณ๋ก ๋ถ๊ธฐ ์ฒ๋ฆฌ ํ๋๋ผ ์ฝ๋๊ฐ ๋งค์ฐ ๋ณต์ก
if๋ฌธ์ผ๋ก ๋ถ๊ธฐํ๋ฉด์ ์ฝ๋ฉํ๊ธฐ ๋๋ฌธ์ ๋ณด๊ธฐ๋ ์ด๋ ค์.
app.js์์ app.get ๊ฐ์ ๋ฉ์๋๊ฐ ๋ผ์ฐํฐ ๋ถ๋ถ์ด๋ค. ๋ผ์ฐํฐ๋ฅผ ๋ง์ด ์ฐ๊ฒฐํ๋ฉด app.js ์ฝ๋๊ฐ ๋งค์ฐ ๊ธธ์ด์ง๋ฏ๋ก ์ต์คํ๋ ์ค์์๋ ๋ผ์ฐํฐ๋ฅผ ๋ถ๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณต
routes ํด๋๋ฅผ ๋ง๋ค๊ณ ๊ทธ ์์ index.js์ user.js๋ฅผ ์์ฑ
/// routes/index.js
const express = require('express');
const router = express.Router();
// GET / ๋ผ์ฐํฐ
router.get('/', (req, res) => {
res.send('Hello, Express'); // โ
์ด๊ฑฐ๋ฅผ ๋ณด๋ธ๋ค
});
module.exports = router; // โ
์ด๊ฑฐ ๋ฌ์์ค์ผ ํ๋ค.
///routes.user.js
const express = require('express');
const router = express.Router();
// GET /user ๋ผ์ฐํฐ
router.get('/', (req, res) => {
res.send('Hello, User'); // โ
์ด๊ฑฐ๋ฅผ ๋ณด๋ธ๋ค
});
module.exports = router; // โ
์ด๊ฑฐ ๋ฌ์์ค์ผ ํ๋ค.
/// app.js
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const dotenv = require('dotenv');
const path = require('path');
dotenv.config();
const indexRouter = require('./routes'); // โ
์ฐ๊ฒฐํ ๊ฒฝ๋ก
const userRouter = require('./routes/user'); // โ
์ฐ๊ฒฐํ ๊ฒฝ๋ก
const app = express();
app.set('port', process.env.PORT || 3000);
app.use(morgan('dev'));
app.use('/', express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: 'session-cookie',
}));
app.use('/', indexRouter); // โ
url ์ค์
app.use('/user', userRouter); // โ
url ์ค์
app.use((req, res, next) => {
res.status(404).send('Not Found');
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '๋ฒ ํฌํธ์์ ๋๊ธฐ ์ค');
});
์ด๋ ๊ฒ ๋ง๋ค์ด์ง index.js์ user.js๋ฅผ app.use๋ฅผ ํตํด app.js์ ์ฐ๊ฒฐํ๋ค
์๋ฌ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด ์์ 404์ํ ์ฝ๋ ์๋ตํ๋ ๋ฏธ๋ค์จ์ด๋ฅผ ์ถ๊ฐ
indexRouter๋ฅผ ./routes๋ก requireํ ์ ์๋ ์ด์ ๋ index.js๋ ์๋ตํ ์ ์์
require('./routes/index.js')์ require('routes')์ ๊ฐ๋ค
์ด์ ์ ์์ next('route') ์์๋ณด์
์ด ๊ธฐ๋ฅ์ ๋ผ์ฐํฐ์ ์ฐ๊ฒฐ๋ ๋๋จธ์ง ๋ฏธ๋ค์จ์ด๋ค์ ๊ฑด๋๋ฐ๊ณ ์ถ์๋ ์ฌ์ฉ.
router.get('/', (req, res, next) => {
next('rotue');
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
}, (req, res, next) => {
console.log('์คํ๋์ง ์์ต๋๋ค');
next();
});
router.get('/', (req, res) => {
console.log('์คํ๋๋ค.');
res.send('hello express');
});
๋ผ์ฐํฐ ์ฌ๋ฌ๊ฐํผ next๋ฅผ ํธ์ถํ๋ฉด ๋ค์ ๋ฏธ๋ค์จ์ด ์คํ๋๋ค.
์ฒซ๋ฒ์งธ ๋ผ์ฐํฐ์ next()๋์ next('route')๋ฅผ ํธ์ถํด์ ๋์ ์ด ์ฃผ์์ ์ผ์นํ๋ ๊ฑธ๋ก ์ด๋
๋ผ์ฐํฐ ์ฃผ์์๋ ์ ๊ทํํ์์ ๋น๋กฏํ ํน์ ํจํด์ ์ฌ์ฉํ ์ ์์.
์ฌ๋ฌ ๊ฐ์ง ํจํด์ด ์์ง๋ง, ์์ฃผ ์ฐ์ด๋ ํจํด ํ๋๋ง ์์๋ณด์.
router.get('/user/:id', (res, req) => {
console.log(req.params, req.query);
});
๋ฌธ์ ๊ทธ๋๋ก :id๋ฅผ ์๋ฏธํ๋ ๊ฒ์ด ์๋. ์ด ๋ถ๋ถ์๋ ๋ค๋ฅธ ๊ฐ์ ๋ฃ์ ์ ์์
์๋ฅผ ๋ค๋ฉด /user/123, /user/1 ๋ฑ์ ์์ฒญ๋ ์ด ๋ผ์ฐํฐ๊ฐ ์ฒ๋ฆฌํจ.
์ด ๋ฐฉ์์ ์ฅ์ ์ :id์ด๋ฉด ํด๋นํ๋ 1์ด๋ 123์ ์กฐํํ ์ ์๋ค๋ ์ req.params ๊ฐ์ฒด ์์ ๋ค์ด ์๋ค.
:id์ด๋ฉด req.params.id๋ก :type์ด๋ฉด req.params.type์ผ๋ก ์กฐํํ ์ ์๋ค.
๋จ, ์ด ํจํด ์ฌ์ฉํ ๋ ์ฃผ์์ . ์ผ๋ฐ ๋ผ์ฐํฐ๋ณด๋ค ๋ค์ ์์นํด์ผ ํจ.
๋ค์ํ ๋ผ์ฐํฐ๋ฅผ ์์ฐ๋ฅด๋ ์์ผ๋ ์นด๋ ์ญํ ์ด๋ผ ์ผ๋ฐ ๋ผ์ฐํฐ ๋ณด๋ค ๋ค์ ์์ด์ผ ๋ฐฉํดํ์ง ์์.
router.get('/user/:id', (req, res) => {
console.log('์๋ง ์คํ๋ฉ๋๋ค.');
});
router.get('/user/like', (req, res) => {
console.log('์คํ๋์ง ์๋๋ค.');
});
/user/like์ ๊ฐ์ ๋ผ์ฐํฐ๋ /user/:id ๊ฐ์ ๋ผ์ฐํธ ๋งค๊ฐ๋ณ์ ์์ ๋์ด์ผ ํจ.
์ฃผ์์ ์ฟผ๋ฆฌ์คํธ๋ง ์ฐ๋ ๊ฒฝ์ฐ๋ ์์.
/user/123?limit=5&skip=10
req.params์ req.query๊ฐ์ฒด๋ ๋ค์๊ณผ ๊ฐ์
{ id: '123' } { limit: '5', skip: '10' }
app.js์์ ์๋ฌ ์ฒ๋ฆฌ ๋ฏธ๋ค์จ์ด ์์ ๋ฃ์ด๋ ๋ฏธ๋ค์จ์ด๋ ์ผ์นํ๋ ๋ผ์ฐํฐ๊ฐ ์์ ๋ 404์ํ ์ฝ๋๋ฅผ ์๋ตํ๋ ์ญํ .
app.use((req, res, next) => {
res.status(404).send('Not Found');
});
์ด ๋ฏธ๋ค์จ์ด๋ฅผ ์ ๊ฑฐํ๊ณ localhost:3000/abc์ ์ ์ํ๋ฉด 404์ํ์ ํจ๊ป ๋ฉ์์ง๊ฐ ์๋ต๋๋ค.
๋ผ์ฐํฐ์์ ์์ฃผ ์ฐ์ด๋ ํ์ฉ๋ฒ์ผ๋ก app.route๋ router.route๊ฐ ์๋ค.
router.get('/abc', (req, res) => {
res.send('GET /abc');
});
router.post('/abc', (req, res) => {
res.send('POST /abc');
});
// ์๋์ฒ๋ผ ๋ฌถ๊ธฐ๋ ๊ฐ๋ฅ
router.route('/abc')
.get((req, res) => {
res.send('GET /abc');
}).post((req, res) => {
res.send('POST /abc');
});
# req, res ๊ฐ์ฒด ์ดํด๋ณด๊ธฐ
์ต์คํ๋ ์ค์ req, res ๊ฐ์ฒด๋ http ๋ชจ๋์ req, res ๊ฐ์ฒด๋ฅผ ํ์ฅํ ๊ฒ์ด๋ค. ๊ธฐ์กด http ๋ชจ๋์ ๋ฉ์๋๋ ์ฌ์ฉํ ์ ์๊ณ , ์ต์คํ๋ ์ค๊ฐ ์ถ๊ฐํ ๋ฉ์๋๋ ์์ฑ์ ์ฌ์ฉํ ์๋ ์๋ค.
์ฒด์ด๋์ ํตํด ์ฝ๋์์ ์ค์ผ ์ ์๋ค.
res
.status(201)
.cookie('test', 'test')
.redirect('/admin');
# ํ ํ๋ฆฟ ์์ง ์ฌ์ฉํ๊ธฐ
HTML์ ์ ์ ์. ๊ทธ๋์ ๋ํ์ ํ ํ๋ฆฟ์์ง์ธ pug์ ๋์ ์ค ์์๋ณผ ์์ .
# ํผ๊ทธ(์ ์ด๋), ๋์ ์ค๋ ์ฑ ์ ๋ณ๋๋ก ์ดํด๋ณด์.
๊ทธ๋ ๊ฒ ์ด๋ ต์ง ์์. ๋ฌธ๋ฒ์ ๋ํ ๋ถ๋ถ.
์์ ์ด๋ฆ์ธ ์ ์ด๋(Jade)๋ก ๋ ์ ๋ช ํจ. ๋ฃจ๋น ์ฌ์ฉํด ๋ณด์๋ค๋ฉด ๋ฌธ๋ฒ์ด ๋น์ทํด์ ๋น ๋ฅด๊ฒ ์ ์ํ ์ ์์.
ํผ๊ทธ ์ค์นํ๊ธฐ
npm i pug
์ต์คํ๋ ์ค์ ์ฐ๊ฒฐํ๋ ค๋ฉด ๋ค์ ๋ถ๋ถ์ด ์์ด์ผ ํจ
/// app.js
...
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views')); // โ
app.set('view engine', 'pug'); // โ
app.use(morgan('dev'));
...
views๋ ํ ํ๋ฆฟ ํ์ผ๋ค์ด ์์นํ ํด๋๋ฅผ ์ง์ ํ๋ ๊ฒ. res.render ๋ฉ์๋๊ฐ ์ด ํด๋ ๊ธฐ์ค์ผ๋ก ํ ํ๋ฆฟ ์์ง์ ์ฐพ์์ ๋ ๋๋ง ํจ.
re.render('index')๋ผ๋ฉด views/index.pug๋ฅผ ๋ ๋๋งํ๋ค. res.render('admin/main')์ด๋ผ๋ฉด views/admin/main.pug๋ฅผ ๋ ๋๋ง
view engine์ ์ด๋ ํ ์ข ๋ฅ์ ํ ํ๋ฆฟ ์์ง์ ์ฌ์ฉํ ์ง๋ฅผ ๋ํ๋ธ๋ค. ํ์ฌ pug๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ๊ทธ๋๋ก ์ฌ์ฉํ๋ฉด ์๋๋ค.
'๐ฐ๏ธ Node.js' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Node.js] ๋ชฝ๊ณ ๋๋น (0) | 2023.08.10 |
---|---|
[Node.js] #7 MySQL (0) | 2023.07.23 |
[Node.js] #5 ํจํค์ง ๋งค๋์ (0) | 2023.07.23 |
[Node.js] #4 http ๋ชจ๋๋ก ์๋ฒ ๋ง๋ค๊ธฐ (0) | 2023.07.22 |
[Node.js] #3 ๋ ธ๋ ๊ธฐ๋ฅ ์์๋ณด๊ธฐ (0) | 2023.07.22 |