블로그 내 코드 자료 출처
Node.js 교과서 개정2판(지음이 조현영)
클라이언트 식별을 위해 필요한 정보
writeHead
에 Set-Cookie
를 하면 된다.
const http = require('http')
const server = http.createServer((req,res) => {
console.log(req.url, req.headers.cookie)
res.writeHead(200, {'Set-Cookie' : 'mycookie=test'})
//쿠키가 자동적으로 req를 통해 data를 주고 있다.
res.end('cookie example')
})
server.listen (3000, () => {
console.log('3000번 포트로 실행중입니다. cookie 확인 중이에요.')
})
server.on('error', err=>{
console.error(err)
})
아래와 같이 value를 바꾸고 새로고침하면
아래와 같이 쿠키가 바뀌었음을 알 수 있다.
하지만 우리가 코드에서 Set-cookie했기 때문에 바로 다시 setting된다.
const http = require('http')
const fs = require('fs').promises
const url = require('url') //url해석
const qs = require('querystring')//쿼리 스트링
////////////////////////////////////////////////////////////////////////////
//1번 구역
//쿠키를 그대로 안쓰고 parse할 것이다.
const parseCookies = (cookie='') => {
//함수 파라미터를 바로 초기화 하는 방법도 있다. 앞으로안들어올텐데 필요한 경우다
return cookie //mycookie=test
.split('.')
.map(v=> v.split('='))
.reduce((acc,[k,v]) => {
acc[k.trim()] = decodeURIComponent(v)
// acc불러와서 trim처리 한다. 앞뒤 공백 삭제
return acc
},{}) // reduece할때 초기화 하는 부분이다.
}
////////////////////////////////////////////////////////////////////////////
const server = http.createServer(async (req,res) => {
const cookie = await parseCookies(req.headers.cookie)
console.log(cookie)
res.writeHead(302, { 'Set-Cookie' : 'name=kyc'})
res.end('success')
})
server.listen(3000, () => {
console.log('포트 3000에서 login 서버 실행중')
})
const http = require('http')
const fs = require('fs').promises
const url = require('url') //url해석
const qs = require('querystring')//쿼리 스트링
////////////////////////////////////////////////////////////////////////////
//1번 구역
//쿠키를 그대로 안쓰고 parse할 것이다.
const parseCookies = (cookie='') => {
//함수 파라미터를 바로 초기화 하는 방법도 있다. 앞으로안들어올텐데 필요한 경우다
return cookie //mycookie=test 책에서는 return이 생략되어 있다.
.split('.')
.map(v=> v.split('='))
.reduce((acc,[k,v]) => {
acc[k.trim()] = decodeURIComponent(v)
// acc불러와서 trim처리 한다. 앞뒤 공백 삭제
return acc
},{}) // reduece할때 초기화 하는 부분이다.
}
////////////////////////////////////////////////////////////////////////////
const server = http.createServer(async (req,res) => {
const cookie = parseCookies(req.headers.cookie) //name={프론트에서 받은 텍스트}
// const {name} = cookie
if(req.url.startsWith('./login')) {
const {query} = url.parse(req.url)
const {name} = qs.parse(query)
//Expires 설정
const expires = new Date()
expires.setMinutes(expires.getMinutes() + 1) //현재 분에서 5분 추가 뜻은 현재 시간부터 1분 까지
// console.log(cookie)//중간 확인용
//Location이라는 옵션을 준다. redirect임
//응답을 한다음 page를 어디 갈것이냐는 재 전송을 해줄 수 있다.
//전송이 끝난 다음에 해당 url로 이동해! 할 수 있음.
//지금은 '/' 즉 'home'으로 설정한 것이고 redirect라고 한다.
res.writeHead(302, {Location: '/',
'Set-Cookie' : `name=${encodeURIComponent(name)};
Expires=${expires.toGMTstring()}; httpOnly; path=/`})
res.end(`success, ${name}`)
}
// name이라는 쿠키가 있는 경우
else if (cookies.name) {
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'})
res.end(`<h1>${cookies.name}님 안녕하세요!<h1>`)
} else {
try {
const data = await fs.readFile('./cookie.html')
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'})
res.end(data)
} catch(err) {
res.writeHead(500)
res.end(err.message)
}
}
})
server.listen(3000, () => {
console.log('포트 3000에서 login 서버 실행중')
})
```js
`new Date()` 현재 시간 객체
`getMinutes()` 현재시간 분 가져오기
`setMinutes()` 분 설정하기
### 강사님 코드 참고할것
```js
const http = require('http')
const fs = require('fs').promises
const url = require('url')
const qs = require('querystring')
const parseCookie = (cookie = '') => {
return cookie
.split('.')
.map(v => v.split('='))
.reduce((acc, [k,v]) => {
console.log(k, v)
acc[k.trim()] = decodeURIComponent(v)
console.log(acc[k.trim()])
return acc
}, {})
}
const server = http.createServer(async (req, res) => {
const cookies = parseCookie(req.headers.cookie)
if(req.url.startsWith('/login')) {
console.log("URL:", req.url)
const { query } = url.parse(req.url)
console.log(query)
const { name } = qs.parse(query)
console.log(name)
const expires = new Date()
expires.setMinutes(expires.getMinutes() + 1)
res.writeHead(302, {
Location: '/',
'Set-Cookie': `name=${encodeURIComponent(name)}; Expires=${expires.toGMTString()}; httpOnly; path=/`})
res.end()
} else if (cookies.name) {
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'})
res.end(`<h1>${cookies.name}님 안녕하세요!<h1>`)
} else {
try {
const data = await fs.readFile('./cookie.html')
res.writeHead(200, {'Content-Type':'text/html; charset=utf-8'})
res.end(data)
} catch(err) {
res.writeHead(500)
res.end(err.message)
}
}
})
server.listen(3000, ()=>{
console.log('3000번 포트에서 로그인서버 실행중!')
책 참고하여 자습하자
Npm(Node package manager)
1. Npm에는 몇 백만개의 패키지가 등록되어 있다. 오픈소스 생태계.
2. 다른 사람이 올려놓은 모듈을 다운받아서 사용할 수 있음.
3. YARN은 페이스북에서 만든 패키지 매니저 Npm이 잘안될때 사용하면 됨.
4. 기본적으로 오픈소스는 무료로 이용하지만 라이선스 확인 꼭 해야함.
(ISC,MIT,BSD 괜찮음! GPL라이센스 조심.)
콘솔을 키고 npm 폴더경로에서 (폴더를 만들고) 콘솔에다가 npm init을 입력
사진과 같이 되며 package.json
이 생성된다.
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields and exactly what they do.
Use `npm install <pkg>` afterwards to install a package and save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (폴더명) [프로젝트 이름 입력]
version: (1.0.0) [프로젝트 버전 입력]
description: [프로젝트 설명 입력]
entry point: index.js
test command: [엔터 키 클릭]
git repository: [엔터 키 클릭]
keywords: [엔터 키 클릭]
author: [여러분의 이름 입력]
license: (ISC) [엔터 키 클릭]
About to write to C:\Users\zerocho\npmtest\package.json:
{
"name": "npmtest",
"version": "0.0.1",
"description": "hello package.json",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "ZeroCho",
"license": "ISC"
}
Is this ok? (yes) yes
그리고 npm install morgan cookie-parser express-session 입력하여 express를 설치하자.
npm install express
를 해야된다.(22-01-21)
아래 처럼 변경되었다.
express에도 모듈이 포함되었다. 자세한 내용은 함께 생성된 package-lock.json
을 확인하자. node_modules 폴더를에서 express 코드를 확인.
그리고 npm i -D nodemon을 입력한다. develop모드의 nodemon이다.
npx nodemon 입력한다. nodemon을 전역에서 사용하겠다는 뜻
http모듈로 웹서버 만드는게불편해서 나온 프레임 워므(REST api 메서드를ㅞㅡ...
index.js
에 아래코드를 입력하여 서버를 만들자.
무려 실시간이다. npx nodemon의 힘이다.
const express = require('express')
const app = express()
app.set('port', 3000)
app.get('/',(req,res)=> {
//'/'저 주소로 get을 처리하겠다.
res.send('Hello, Express')
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
app.set(키 밸류)
app.get(키): app.set으로 설정한
app.get(주소, 라우터 콜백) : 콜백함수(req,res) => { res.send('데이터)}
//2차 실습
const path = require('path')
//리눅스 환경에서 사용하든, 윈도우에서 사용하든 /\호환 시킴
const express = require('express')
const app = express()
app.set('port', 3000)
app.get('/',(req,res)=> {
//'/'저 주소로 get을 처리하겠다.
// res.send('Hello, Express')
// 전에는 require('fs')사용하여 했지만 지금은 sendFile만으로도 가능하다.
//이렇게 html을 참조할 것이다.
res.sendFile(path.join(__dirname, '/index.html'))
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
미들웨어 : 요청과 응답 중간에서 조작하는 역할
사용방법 :
app.use((
req,res,next) => {
...처리할 내용
next()
}
//3차 실습
const path = require('path')
//리눅스 환경에서 사용하든, 윈도우에서 사용하든 /\호환 시킴
const express = require('express')
const { copyFileSync } = require('fs')
const app = express()
app.set('port', 3000)
app.use((req, res, next) => {
//app.use를 먼저 통과하고 app.get으로 향하게 될 것이다.
console.log('모든 요청에서 실행 됩니다.')
next()
})
app.get('/',(req,res)=> {
//'/'저 주소로 get을 처리하겠다.
// res.send('Hello, Express')
// 전에는 require('fs')사용하여 했지만 지금은 sendFile만으로도 가능하다.
//이렇게 html을 참조할 것이다.
res.sendFile(path.join(__dirname, '/index.html'))
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
미들웨어로 예외처리 가능함을 실습한다.
강제 에러 발생시킴
//4차 실습
const path = require('path')
//리눅스 환경에서 사용하든, 윈도우에서 사용하든 /\호환 시킴
const express = require('express')
const { copyFileSync } = require('fs')
const app = express()
app.set('port', 3000)
// app.use((req, res, next) => {
// //app.use를 먼저 통과하고 app.get으로 향하게 될 것이다.
// console.log('모든 요청에서 실행 됩니다.')
// next()
// })
app.get('/',(req,res,next) => {
console.log('GET / 요청에서 실행됩니다.')
next()
}, (req,res)=> {
//'/'저 주소로 get을 처리하겠다.
// res.send('Hello, Express')
// 전에는 require('fs')사용하여 했지만 지금은 sendFile만으로도 가능하다.
//이렇게 html을 참조할 것이다.
throw new Error('에러를 미들웨어에서') //4차내용 일부러 error냄
res.sendFile(path.join(__dirname, '/index.html'))
})
app.use((err,req,res,next) => {
console.error(err)
res.send(err.message)
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
//내코드
app.get('/',(req,res,next) => {
console.log('GET / 요청에서 실행됩니다.')
next()
}, (req,res)=> {
throw new Error('에러를 미들웨어에서') //4차내용 일부로 error냄
res.sendFile(path.join(__dirname, '/index.html'))
})
//강사님코드
app.use('/', (req, res, next) => {
console.log('GET / 요청에서 실행됩니다.')
next()
},)
app.get('/', (req, res) => {
throw new Error('에러를 미들웨어에서')
res.sendFile(path.join(__dirname, '/index.html'))
})
morgan, cookieParser, sesseion
//5차 실습
const path = require('path')
const express = require('express')
const morgan = require('morgan') // 5차에서 추가함
const cookieParser = require('cookie-Parser') // 5차에서 추가함
const session = require('express-session') // 5차에서 추가함
const app = express() // 맨위에 있어야함
app.use(morgan('dev')) //5차에서 추가함
app.use('/', express.static(path.join(__dirname, 'public')))//5차
//예제를 위해 npm폴더 안에 public폴더를 만들자 그리고 test.txt만들자
//'/'정적파일 경로를 써주게 되면 접근을 할 수 있다.
//폴더 경로는 path.join~~~~부터이다.
app.set('port', 3000)
app.get('/',(req,res,next) => {
console.log('GET / 요청에서 실행됩니다.')
next()
}, (req,res)=> {
res.sendFile(path.join(__dirname, '/index.html'))
})
app.use((err,req,res,next) => {
console.error(err)
res.send(err.message)
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
브라우저 주소창에 test.txt를 넣었다.
브라우저 주소창에 JS 썸네일2.png를 넣었다.
아래 사진처럼 타인의 서버에도 접근이 가능하다.
동영상은 아마 안될것이다. 아마.
//6차 실습
const path = require('path')
const express = require('express')
const morgan = require('morgan')
const cookieParser = require('cookie-Parser')
const session = require('express-session')
const app = express() // 맨위에 있어야함
app.use(morgan('dev'))
app.use('/', express.static(path.join(__dirname, 'public')))
app.use(express.json()) // 6차
app.use(express.urlencoded({extended:false}))// 6차
// app.use(cookieParser) //6차 그냥 이런게 있다 정도면 알자
app.use(session({
//6차 그냥 이런게 있다 정도면 알자
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false
},
name: 'session-cookie'
}))
app.set('port', 3000)
app.get('/',(req,res,next) => {
console.log('GET / 요청에서 실행됩니다.')
next()
}, (req,res)=> {
res.sendFile(path.join(__dirname, '/index.html'))
})
app.use((err,req,res,next) => {
console.error(err)
res.send(err.message)
})
const port = app.get('port')
app.listen(port, () => {
console.log(port, '번 포트에서 서버 실행 중')
})
json.parse()
,json.stringfy()
등이 기억날 것이다.console에 npm i multer를 입력한다. multer 패키지 설치
//내코드
const express = require('express')
const multer = require('multer')
const path = require('path')
const app = express()
const upload = multer({
//스토리지 설정할 것임
storage: multer.diskStorage({
//목적지 설정할 것임
destination(req,file,done) {
//done 인자는 함수형이다.
done(null, 'uploads/')//업로드 하면 어디다 저장할 것이냐
},
filename(req,file,done) {
//아래는 들어온 파일 이름을 어떻게 설정할지이다.
const ext = path.extname(file.originalname)//확장자 이름 설정
done(null, path.basename(file.originalname, ext) + Date.now() + ext)
//basename은 현재경로를 따서...
//↑ 현재 파일이름을 비교하여서 현재 시간을 넣어준다
//file.originalname 확장자 이름을 가져와서 현재시간 넣고, 확장자 넣고.. 조합을 한다.?
},
limits: {fileSize:5*1024*1024}
})
})
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'multi.html'))
})
//upload에 파일을 넘겼을 때 파일을 업로드 할 수 있다.
app.post('/upload', upload.single('image'),(req,res) => {
console.log(req.file, req.body)
res.send('ok')
})
app.listen(3000, () => {
console.log('3000번 포트에서 실행 중, multer 파일 서버')
})
//강사님 코드
const express = require('express')
const app = express()
const multer = require('multer')
const path = require('path')
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('/', (req, res) => {
res.sendFile(path.join(__dirname, 'multi.html'))
})
app.post('/upload', upload.single('image'), (req, res) => {
console.log(req.file, req.body)
res.redirect('/')
})
app.listen(3000, ()=> {
console.log('3000포트에서 실행중, multer 파일 서버')
})
파일 선택을 하고 업로드 하면 내 폴더에 해당 파일이 업로드 됨을 확인 가능하다.
upload.array('many')
를 사용하자.type=file, multiple
속성을 추가해 주면된다.하위로 routes폴더 만들고, index.js만들고, user.js만들자
현재 폴더인 npm폴더에는 app.js만들자.
//app-route.js
const express = require('express')
const app = express()
const indexRouter = require('./routes')
const userRouter = require('./routes/user')
app.use('/', indexRouter) // 미들웨어를 통해 모듈을 분리 할 수도 있다.
app.use('/user', userRouter) // /user에 접근하면 -> app.use('/user..에 걸리는거다.
//여기 까지 뜻은 나는 app-route.js를 실행할건데
// app.use에서 '/'에 결리면 indexRouter에 걸려서 즉, index.js가 실행된다.
// app.use에서 '/user'에 결리면 userRouter에 걸려서 즉, user.js가 실행된다.
app.listen(3000, () => {
console.log('3000번 포트에서 서버 실행 중')
})
//index.js
const express = require('express')
const router = express.Router()
router.get('/',(req,res) => {
//라우터에 하나씩 연결하자
res.send('Hello Express')
})
module.exports = router
//user.js
const express = require('express')
const router = express.Router()
router.get('/',(req,res) => {
//라우터에 하나씩 연결하자
// /user/
//브라우저에 검색 http://localhost:3000/user
res.send('Hello user')
})
router.get('/test',(req,res) => {
// /user/test/
res.send('Heool~~ user')
})
router.get('/:id',(req,res) => {
console.log(req.params.id)
res.send(req.params.id)
// 브라우저에 검색하고 그리고 jsh를 다른걸로 치면 반응이 나온다. http://localhost:3000/user/jsh
})
module.exports = router
아래와 같이 사용가능
req.get....
req.send...
req.use...
req
.get
.send
.use
db시간에 만들었던 db사용!
폴더를 새로 만들었으니, npm 모듈을 새로 깔자.
아래 순서 참고
models폴더 index.js 실행 후 내용 수정할 것이다.
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
//↓ 시퀄라이즈 새로 쳐준다.
const sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
)
db.sequelize = sequelize;
module.exports = db;
넌정스랑 vue html은 책에 잇지만 필요없으니 안한다.
현재 폴더 (express-ssq)에서 app.js생성한다.그리고 작성한다.
내코드 문제가 있다. 확인 필요. 맨마지막 ('port'여기에 괄호가 없고
locals error massage쪽에 오타가 있다.
//내코드
const express = require('express')
const path = requi('path')
const morgan = require('morgan')
const { sequelize} = require('./models')
const app = express()
app.set('port', process.env.PORT || 3000)
sequelize.sync({force: false})
.then (() => {
console.log("데이터 베이스 연결 성공")
})
.catch((err) => {
console.error(err)
})
app.use(morgan('dev'))
app.use(express.static(path.join(__dirname,'public')))
app.use(express.json())
app.use(express.urlencoded({extended : false}))
app.use((req,res,next) => {
const error = new Error(`${req.mothod} ${req.url} 라우터가 없습니다.`)
error.status =404
next(error)
})
app.use((err,req,res,next) => {
res.locals.message = process.env.NODE_ENV !== 'production' ? err:{}
res.status(err.status || 500)
res.render('error')
})
app.listen(app.get('port', () => {
console.log(app.get('port'), '번 포트에서 대기중!')
}))
//강사님 코드
const express = require('express')
const path = require('path')
const morgan = require('morgan')
const { sequelize } = require('./models')
const app = express()
app.set('port', process.env.PORT || 3000)
sequelize.sync({force: false})
.then(() => {
console.log("데이터 베이스 연결 성공")
})
.catch((err) => {
console.error(err)
})
app.use(morgan('dev'))
app.use(express.static(path.join(__dirname, 'public')))
app.use(express.json())
app.use(express.urlencoded({ extended: false}))
app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`)
error.status = 404
next(error)
})
app.use((err, req, res, next) => {
res.locals.message = err.message
res.locals.error = process.env.NODE_ENV !== 'production' ? err : {}
res.status(err.status || 500)
res.render('error')
})
app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 대기중!')
})
이제 테이블을 만들것이다.
Sequelize.STRING //varchar(255)
Sequelize.string(1234)//varchar(1234)
Sequelize.integer//integer
Sequelize.json//json column.PostrgreSQL, SQLite and MYSQL only
Sequelize.jsonb//jsonb column. PostgreSQL only
Sequelize.boolean//boolean
const Sequelize = require('sequelize')
module.exports = class Department extends Sequelize.Model {
static init(sequelize) {
return super.init({
name: {
type: Sequelize.STRING(50)
},
code: {
type: Sequelize.STRING(50)
},
description: {
type: Sequelize.TEXT
}
}, {
sequelize,
timestamps: true,
underscored: false,
modelName: 'Departments',
tableName: 'departsments',
paranoid: false,
charset: 'utf8',
collate: 'utf8_general_ci'
})
}
// static associate(db) {
// db.Department.hasMany(db.User, { foreignKey: 'departmentId', sourceKey: 'id'})
// }
}
※ class의 Department
말고는 모두고정적으로 쓴다.
모델 만들기
PK : id(int) PK NOT NULL(자동 증가 시퀀스)
class 설명
모델을 만들었다면 table이 만들어 졌음을 확인 할 수 있다.
.get을 사용하면 department.findAll()하면 해당 모듈 속성을 객체형식으로 가져온다.
.post를 사용하면 req.body 즉 body에 create함수를 사용하여 item을 생성해줄 수 있다.
내가 insert할 것을 넣는 것이다.
※쿼리를 쓰게되면 복잡해진다. 그런데 시퀄라이즈를 사용하면 create만 써서 입력 가능하다.
입력에 성공하면 응답으로 json형태로 반환한다.
.put 수정도 .post와 동일하다.
.delete는 id를 기준으로 삭제한다.
이 뒤로 부터는 시간이 없다. 책을 보고 자습하고 우선 강사님 코드로 진행한다.
강사님이 주신 전체 압축파일을 해제 후,
/users 에 get post날리면 사용자 목록 보고 할 수 있다. 미들웨어 등록해서 접근해서 patch delete등 조작 가능
ctrl+s 누르면 저장된다. 중간중간 저장하자.
pgAdmin에 들어왔음을 확인 가능하다.
patch
delete 바로 지울 수 있다.