multer는 multi-part/form-data 데이터를 처리하기 위해 만든 미들웨어이다. 쉽게 말해 클라이언트에서 전송한 파일을 쉽게 업로드 할 수 있도록 도와주는 미들웨어이다.
npm install multer
Node.js 서버로 파일을 업로드하는 html 코드를 작성해보자.
<!DOCTYPE html>
<html>
<head>
<title>multer 사용하기</title>
</head>
<body>
<form
action="http://localhost/profile"
method="post"
enctype="multipart/form-data"
>
<input type="file" name="avatar" />
<input type=""submit" value="업로드"/>
</form>
</body>
</html>
이 코드를 모두 작성한 뒤, 프로젝트 폴더에 uploads
폴더를 만든다.
multer 모듈을 사용하여 클라이언트로부터 전송된 파일을 업로드 처리하기 위해서는 먼저 디스크 저장장소에 대한 객체를 생성해야 한다. 이 때 diskStorage()
함수를 사용하여 파일이 저장될 위치, 파일명을 지정해준다.
//디스크 저장소에 대한 객체 생성하기
const storage = multer.diskStorage({//디스크 저장소의 정의
destination: function(req, file, cb){
cb(null, 'uploads/') //파일이 저장될 위치 정의하기
},
filename: function(req, file, cb){ //파일명 지정하기
//cb(null, file.originalname) //cb 콜백함수를 통해 전송된 파일 이름 설정
cb(null, new Date().valueOf() + path.extname(file.originalname)); //시스템 시간으로 파일 이름 설정
}
})
app.js에서 라우터를 아래와 같이 작성하면 multer 모듈을 사용해 파일 업로드를 처리할 수 있다.
const express = require("express");
const multer = require("multer");
const path = require('path');
const static = require('serve-static');
const app = express();
app.use(express.urlencoded({extended:true})); // url : Uniform Resource
app.use(express.json());
app.listen(3000, () => {
//3000번 포트로 서버 실행
console.log("Server started. port 3000.");
});
const upload = multer({storage: storage}); //multer 객체 생성
//클라이언트로 전송된 파일을 multer 모델을 사용하여 업로드 처리하기
app.post('/profile', upload.single('avatar'), function (req, res, next){
console.log(req.file);
console.log(req.body);
})
이 때, upload.single()의 괄호 안에 적힌 문자열(여기서는 avatar)과 form이 있는 html의 name 부분이 일치하는지 확인해야 한다.
파일을 선택한 뒤 업로드 버튼을 누르면,
console.log(req.file)의 결과가 잘 찍히는 걸 확인할 수 있다.
여기까지가 이미지를 uploads 폴더에 저장하는 부분이다.
이제 클라이언트가 선택한 파일을 화면에 띄워보자. 띄우기 위해서는 ejs에 대해 알아야 한다.
아직 나도 ejs는 잘 모르는데, 아래 링크를 참고하였다.
public 폴더 밑에 photo.ejs
라는 파일을 생성한 뒤 아래와 같이 코드를 작성한다.
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<title>my photo</title>
</head>
<body>
<img id="photo">
<script>
document.getElementById("photo").src = "<%= avatar %>";
</script>
</body>
</html>
photo라는 id를 갖는 img의 src에 avatar라는 이름으로 전달된 값을 저장한다… 내가 이해한 바로는 그렇다 ^_^ 아님 말고~
그리고 app.js 폴더에 아래와 같은 코드를 추가로 작성한다. ejs를 사용하기 위해서 추가해야 한다?
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.static('public'))
app.use('/uploads',express.static('uploads'))
그리고 app.js의 라우터 부분(아까 작성했던) 코드를 수정해준다.
//클라이언트로 전송된 파일을 multer 모델을 사용하여 업로드 처리하기
app.post('/profile', upload.single('avatar'), function (req, res, next){
console.log(req.file)
console.log(req.body);
//여기부터 추가했다.
var path = req.file.path;
//req.file.path의 값은 `uploads\\파일이름`의 형태로 저장돼 있는데,
//역슬래시 때문에 그냥 넘겨주면 `uploads파일이름`의 형태가 되어 경로로 사용할 수 없다.
path = path.replace(/\\/g, "/");//역슬래시를 슬래시로 변경해주기
console.log(req.file.path);
console.log(path);
res.render(__dirname + '/public/photo.ejs', {avatar: path})
})
이 때 .ejs 파일의 <%= 변수이름 %> 과 {변수 이름: 데이터}에서 변수이름이 동일해야 함을 기억하자.
이렇게 하고나서, 파일을 선택한 뒤 업로드 버튼을 누르면,
짜잔 아주 귀여운 포챠코가 화면에 나타나는 걸 확인할 수 있다.
실습을 진행한 파일이다.
*아직 공부중인 학생입니다!
복습도 하고 기록도 남기기 위해 사용하는 블로그로 오류가 있을 수 있습니다.
특히 이번 정리 중 ejs는 아직 저도 제대로 공부해보지 못했습니다 ㅠㅅㅠ
참고만 부탁드려요! 오류가 있으면 알려주시면 감사하겠습니다 :)
<참고한 사이트>