포스트

노드 학습 10일차

안녕하세요 마저 공부해보겠습니다

multer

html의 form 태그의 타입이 multipart/form-data 인 데이터를 파싱하는 모듈 입니다.
express의 json() , urlencoded() 를 통해 json 데이터와 form 데이터를 받아올 수 있었지만 multipart/form-data 인 데이터는 파싱하지 못하기 때문에 해당 모듈을 사용합니다.
multipart/form-data 인 경우 데이터는 이미지, 동영상 등의 파일 입니다.

설치 방법

npm i multer

세팅 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const express = require('express');
const multer = require('multer');
const app = express();

const upload = multer({
	storage:multer.diskStorage({
		destination(req,file,done){
//			done(null,{업로드경로})	
			done(null, 'uploads');
		},
		filename(req,file,done){
//			done(null,{파일명})
			const ext = path.extname(file.originalname); // 파일 확장자 추출

			// '파일명+밀리 초 단위의 시간+확장자' 로 파일명을 저장
			done(null, path.basename(file.originalname+Date.now()+ext));
		}
	}),
	limits:{
//		filesize : {파일사이즈}
		filesize : 5 * 1024 * 1024
	}
})

done() 의 첫 번째 인수는 업로드 실패 시 사용될 에러 객체, 두 번째는 파일 업로드가 성공적일 때 반환될 데이터를 의미합니다. 만약 업로드 객체에서 파일의 확장자가 jpg가 아닌 경우에는 파일 업로드를 못하도록 해본다면 다음과 같이 수정할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
//생략
		filename(req,file,done){
//			done(null,{파일명})
			const ext = path.extname(file.originalname); // 파일 확장자 추출

			if(ext !== '.jpg'){
				return done(new Error('jpg만 가능합니다'))
			}
			
			// '파일명+밀리 초 단위의 시간+확장자' 로 파일명을 저장
			done(null, path.basename(file.originalname+Date.now()+ext));
		}
//생략

여기서는 첫 번째 인수로 에러 객체를 전달하여 파일 업로드가 실패했음을 알려주고 있습니다.

사용 방법

1
2
3
4
//예시) app.post('{URL}',upload.single({file의 name속성 값}),(req,res)=>{
app.post('/upload',upload.single('image'),(req,res)=>{
	
})

주석에서 설명한 file의 name 속성 값은 html에서 타입이 file인 input 태그의 name 속성을 의미합니다.

예시)

1
<input type="file" name="이거요"/>

업로드 객체의 기능

.single(fieldname)

하나의 파일만을 업로드 받습니다.

예시)

1
2
3
app.post('/upload',upload.single('image'),(req,res)=>{
	//작업 생략
})
.array(fieldname[, maxCount])

파일을 배열로 받습니다. maxCount 이상의 파일이 전달되면 에러가 발생할 수 있습니다.

예시)

1
2
3
app.post('/upload',upload.array('image',10),(req,res)=>{
	//작업 생략
})

name 속성의 값이 image 이고 10개까지의 파일을 업로드 받는 라우트

.fields(fields)

fields 에 선언된 파일들을 받습니다.

예시)

1
2
3
4
5
6
app.post('/upload',upload.fileds([
	{name:'hand',maxCount:5},
	{name:'foot',maxCount:10}
]),(req,res)=>{
	// 작업 생략
})

name의 속성 값이 hand인 요소에서는 5개를 받고 foot인 요소에서는 10개까지 받는 라우트

.none()

텍스트만 전달 받습니다. 만약 파일이 업로드 될 경우 LIMIT_UNEXPECTED_FILE 에러를 발생시킵니다. 기능적으로는 upload.fields[{}] 와 같은 동작을 합니다.

.any()

전달된 모든 파일을 허용합니다.

하나의 미들웨어에서만 처리하는 이유?

멀티파트 데이터를 처리하는 작업은 대부분의 경우 모든 라우트에서 발생하는 작업이 아니기 때문 입니다.

1
app.use(upload.single('image'));

만약 제가 위와 같이 미들웨어를 사용했다면 모든 라우트에 대해서 동작하게 되기 때문에 비효율 적입니다. 뿐만 아니라 공식 문서에서도 이는 보안적 취약으로 인해 사용하지 말라 하고 있습니다.
그리고 한 가지 더 궁금했던 예시로 다음과 같은 경우가 있었습니다.

1
2
3
4
app.use('/uploads',upload.single('image'));
app.pose('/uploads',(req,res)=>{
	// 작업 생략
})

사용 방법 에서 봤던 부분과 기능적으로 어떻게 다른지에 대해 궁금했습니다.
여기서 use() 를 사용해 특정 URL에만 미들웨어로써 동작하도록 한다면 모든 HTTP 메서드가 multer 미들웨어를 거치게 되어서 비효율적입니다.
그렇기 때문에 위의 예시와 같이 한 라우트에서만 사용하는 경우라면 라우트에 바로 연결해서 사용하는 것이 리소스 절약에 좋습니다.

파일 정보 확인하기

requst 객체의 file 속성에서 확인할 수 있습니다.

1
2
3
4
app.post('/upload',upload.single('image'),(req,res)=>{
	console.log(req.file);
	res.send('OK');
})

dotenv

프로젝트 내의 .env 파일을 소스코드에서 사용할 수 있도록 돕는 모듈입니다.

설치 방법

npm i dotenv

세팅 방법

app.js 파일 내에서 다음의 코드를 통해 사용을 설정합니다. 파일의 최상단에 위치하는 것이 좋습니다. 그래야 .env 파일에 접근하여 사용할 수 있기 때문입니다.

1
2
const dotenv = require('dotenv');    
dotenv.config();

다음으로 프로젝트 내에 .env 파일을 생성합니다.
여기서 사용할 정보를 키=값 형태로 입력합니다. 이때 세미콜론은 사용하지 않습니다.

예시)

1
COOKIE_SECRET = SECRET

사용 방법

process.env.{사용할키} 의 방법으로 접근하여 사용합니다.
.env 파일에서 저장한 키와 매핑하여 값을 가져옵니다.

예시)

1
2
3
//생략
app.use(cookieParser(process.env.COOKIE_PARSER));
//생략
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.