파일 업로드
파일 업로드 또한 form을 활용한다. 다만 form과 input에 적어주어야 할 속성이 있다.
프론트측 html
<form action="/upload/array" method="POST" enctype="multipart/form-data">
<input type="file" name="userfiles" multiple>
<br>
<input type="text" name="title">
<br>
<button>업로드</button>
</form>
위 코드와 같이 form에는 enctype="multipart/form-data", input에는 type="file"로 설정해주어야 한다.
* input의 multiple은 여러 파일을 첨부할 때 이용한다.
파일을 업로드하기 위해서는 서버에서 multer 라는 미들웨어를 이용, 저장 경로와 이름 등을 미리 설정해 줘야 한다.
-서버측-
const uploadDetail = multer({
// storage: 저장할 공간에 대한 정보
storage: multer.diskStorage({
// destination: 경로 설정
destination(req, file, done) {
// done: 콜백함수
// done(null, xx) : null => 에러가 없다는 의미
done(null, "uploads/"); // 파일을 업로드할 경로 설정,
},
filename(req, file, done) {
// 파일의 확장자 추출 => 'path' 모듈 활용
console.log(req.body);
const ext = path.extname(file.originalname); // 확장자 추출
// done(null, path.basename(file.originalname, ext));
// 확장자를 제외한 파일 이름만
// console.log(path.basename(file.originalname, ext));
done(null, path.basename(req.body.id, ext) + Date.now() + ext);
}
}),
limits: {
fileSize: 5 * 1024 * 1024 // 5MB
}
})
서버측 post, 두 번째 인자에 multer가 들어가는 걸 확인할 수 있다.
// single() 인자는 input 태그의 name 값과 일치시켜야 함
app.post('/upload', uploadDetail.single('userfile'), function(req, res) {
console.log(req.body);
console.log(req.file);
res.redirect('/');
// {
// fieldname: 'userfile', // 폼에 정의한 name 값
// originalname: 'christmas.jpg', // 원본 파일 명
// encoding: '7bit', // 파일 인코딩 타입
// mimetype: 'image/jpeg', // 파일 타입
// destination: 'uploads/', // 파일 저장 경로
// filename: 'christmas1701053957631.jpg', // 저장된 파일 명
// path: 'uploads\\christmas1701053957631.jpg', // 업로드된 파일 전체 경로
// size: 103113 // 파일 크기
// }
})
//2. array() : 하나의 인풋에 여러 파일 업로드
app.post('/upload/array', uploadDetail.array('userfiles'), function(req, res) {
// [{file1 정보}, {file2 정보},...] : 배열 형태
console.log(req.files);
console.log(req.body);
res.send('하나의 파일에 여러 파일 업로드 완료!');
})
// fields() : 여러 파일을 각각의 인풋에 업로드.
app.post('/upload/fields', uploadDetail.fields([{name: 'userfiles1'}, {name: 'userfiles2'}]), function(req, res) {
/*
{
userfile1: [
{ 파일 정보}
],
userfile2: [
{ 파일 정보}
]
}
*/
console.log(req.files);
console.log(req.body);
res.send('여러개의 인풋에 각각의 파일 업로드 완료!')
})
동적 파일 업로드 (axios)
submit을 하면 자동으로 보내주지만, 수동으로 해야하기 때문에 formData를 이용해서 프론트에서 정보를 쏴주고 fetch해야한다.
-프론트측-
function fileUpload() {
// js만으로 폼 전송
// file을 같이 전송 => formData 객체를활용하기!
// FormData란?
// form 태그의 데이터를 동적으로 제어할 수 있는 기능, 보통 axios, ajax 등과 함께 사용
const formData = new FormData();
const file = document.querySelector('#dynamicFile');
const title = document.querySelector('#title');
console.log(file); // 선택한 파일 요소
console.log(file.files); // 업로드한 파일 객체
console.log(file.files[0]); // 업로드한 첫 파일
// append(key, vlaue)
// 주의점! file.files[0]을 다른 것보다 일찍 append하면 서버측 multer를 정의할 때
// req.body가 undefined로 나온다. 그러니까 file append는 뒤로
formData.append('title', title.value);
formData.append('dynamicFile', file.files[0]);
axios({
method: 'post',
url: '/dynamic',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
// enctype 지정과 동일
}
}).then((res) => {
console.log(res.data);
const {file, title} = res.data;
const imgElement = document.querySelector('img');
imgElement.src = '/' + file.path;
imgElement.alt = title;
imgElement.classList.add('profile');
})
}
- 서버측 -
// multer 세부설정
const uploadDetail = multer({
// storage: 저장할 공간에 대한 정보
storage: multer.diskStorage({
// destination: 경로 설정
destination(req, file, done) {
// done: 콜백함수
// done(null, xx) : null => 에러가 없다는 의미
done(null, "uploads/"); // 파일을 업로드할 경로 설정,
},
filename(req, file, done) {
// 파일의 확장자 추출 => 'path' 모듈 활용
console.log(req.body);
const ext = path.extname(file.originalname); // 확장자 추출
// done(null, path.basename(file.originalname, ext));
// 확장자를 제외한 파일 이름만
// console.log(path.basename(file.originalname, ext));
done(null, path.basename(req.body.id, ext) + Date.now() + ext);
}
}),
limits: {
fileSize: 5 * 1024 * 1024 // 5MB
}
})
// 이렇게 req.file 객체로 받을 수 있다.
app.post('/dynamic', uploadDetail.single('dynamicFile'), (req, res) => {
console.log(req.file);
console.log(req.body);
res.send({ file: req.file, title: req.body.title});
})
MVC
소프트웨어 설계와 관련된 디자인 패턴으로
쉽게말해
Model (데이터베이스관련 데이터를 처리하는 부분 )
View(Router = app.get, app.post와 같은 메소드와 view폴더에 들어간 ejs, UI 관련된 것을 처리하는 부분),
Controller(get, post 등에 쓰이는 콜백함수들, view와 model을 연결해주는 부분 )
을 나누어 저장한 것을 말한다.
더 쉽게 설명하자면 찾아보기 편하게 끼리끼리 모으고, 재사용 가능성이 있는 것을 함수 등으로 정의하는 것.
편하자고 하는거다.
장점 유지보수 용이 유연성이 높음 확장성이 높음 협업에 용의 |
단점 완벽한 의존성 분리가 어려움 설계 단계가 복잡 설계 시간이 오래 걸린다 클래스가 많아진다 |
(controller - 함수들), model(database 연결), routes(app.get 등), views(ejs)
module.exports 와 class 등을 이용해서 다른 파일에서도 이를 이용할 수 있게 만들면 된다.
간단하게 말하면 모듈과 클래스를 이용해서 비슷한 것 끼리 같은 파일에 묶는거라고 생각하면 편할 듯 하다.
'포스코x코딩온' 카테고리의 다른 글
[포스코x코딩온] 풀스택 부트캠프 7주차 정리 2 - Cookie, Session, dotenv, aws, 서버구축, jwt (1) | 2023.12.09 |
---|---|
[포스코x코딩온] 풀스택 부트캠프 7주차 정리 1 - Mysql연동, sequelize (0) | 2023.12.05 |
[포스코x코딩온] 풀스택 부트캠프 6주차 정리 1 - form전송, 동적 form 전송 (0) | 2023.11.28 |
[포스코x코딩온] 풀스택 부트캠프 5주차 정리 2 - 구조분해 할당, 스프레드 연산자, promise (0) | 2023.11.23 |
[포스코x코딩온] 풀스택 부트캠프 5주차 정리 -1 (node.js, express.js) (0) | 2023.11.21 |