Multer

김라영·2022년 1월 25일
0

nodejs

목록 보기
1/1

multer를 사용하면서 헷갈렸던 내용을 작성해보려고 한다!

multer의 사용방법은 https://github.com/expressjs/multer/blob/master/doc/README-ko.md 이곳을 참고하시면 됩니다!

multer란?

파일 업로드를 위해서 사용되는 multer/form-data를 다루기 위한 node.js의 미들웨어
즉, 서버는 파일을 제외한 나머지 데이터는 body를 통해서 다른 특별한 처리없이 사용할 수 있지만 파일은 이 미들웨어를 사용해서 처리해야한다!!!!!!

multer에서 처리하는 것들

1.formData를 통해서 서버로 온 데이터
2.HTML에서 form태그를 사용하여 서버로 온 데이터
--> body와 file이 나눠지는 것은 multer가 알아서 처리해서 body객체와 file에 각자 넣어준다.

//formData이용
const formData = new FormData();
    formData.append('id', id.value);
    formData.append('itemName', itemName.value);
    formData.append('itemtype', itemtype.value);
    formData.append('color', color.value);
    formData.append('size', size.value);
    formData.append('value', value.value);
    formData.append('uploadImg', img.files[0]);

    const action = addBox.action;
    const result = await axios.post(`/item/list`, formData, {
        headers: {
            'Content-Type': 'multipart/form-data',
        },
    });
//form태그
<form class="content" method="post" action="/item/list" enctype="multipart/form-data">
	<label for="itemtype">
		<span>타입</span>
		<input id="itemtype" name="itemtype" type="text">
	</label>

	<label for="img">
		<span>이미지</span>
		<input id="img" name="img" type="file" accept="image/*">
	</label>

	<label for="itemName">
		<span>제품명</span>
		<input id="itemName" name="itemName" type="text">
	</label>

	<label for="value">
		<span>가격</span>
		<input id="value" name="value" type="number">
	</label>

	<input type="button" class="submitBut" value="제출"></input>
</form>

multer의 originalname과 filename

둘은 서로 같지 않다!!
그러므로 만약 자신이 지정한 이름으로 서버에 올리고 싶다면 originalname이 서버에 저장되도록 해야한다.

orginalname은 실제 파일이름
filename은 multer가 무작위로 지정해준 이름

originalname을 쓸까 filename을 쓸까

클라이언트가 서버로 보낸 파일의 이름이 동일할 수 있다
그러므로 실제 서버에는 filename을 파일의 이름으로 저장하는 것이 좋을 것 같다.

filename과 orginalname을 모두 DB에 넣어두고 필요할 때 사용하는 것을 추천한다.

path를 꼭 사용해야 할까?

서버에 저장되어있는 파일을 클라이언트로 보내기 위해서는 서버에 저장된 경로를 알아야한다.
이때 사용할 수 있는게 path이므로 저장하는 것을 추천한다.

function getPath(filepath) { //파일 경로 만드는 함수
  const filepatharr = filepath.split('/');
  const realpath = filepatharr.slice(1, filepatharr.length - 1);
  return realpath.join('/');
}
const path = getPath(file.path);

데이터 각각 다른 파일에 저장하려면?(파일 분기처리)

diskStorage를 사용하면 된다.

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    const type = req.body.itemtype;
    cb(null, `./dataFile/dataImg/${type}`);
  },
});

const upload = multer({ storage: storage });

multer를 사용하면 겪은 신기한 문제

클라이언트에서 데이터를 보내주는 것은 맞는데 multer의 req.body가 empty였다

multer body가 없었던 이유


어이없게도 이유가 multer의 사용방법이 정리된 문서에 나와있었다.

클라이언트가 바디로 보내는 순서에 따라 req.body가 들어가지 않을 수도 있었던 것.
즉, 파일을 formData에 먼저 담고 다른 데이터들을 formData에 담아주고 있어서 생긴 일이었다.

클라이언트에서 데이터를 지속적으로 보내도 multer의 req.body가 비어있었다. 정말 이것 오류를 고치느라고 3시간 동안 고민한거 같다ㅠㅠ
꼭꼭 문서를 꼼꼼히 제대로 읽어봐야겠다,,

해결방법

이미지 파일을 formData에 append해주는 부분을 가장 마지막에 해주면 된다.

//문제 코드
const formData = new FormData();
	formData.append('uploadImg', img.files[0]);
    formData.append('id', id.value);
    formData.append('itemName', itemName.value);
    formData.append('itemtype', itemtype.value);
    formData.append('color', color.value);
    formData.append('size', size.value);
    formData.append('value', value.value);
    
//해결
const formData = new FormData();
    formData.append('id', id.value);
    formData.append('itemName', itemName.value);
    formData.append('itemtype', itemtype.value);
    formData.append('color', color.value);
    formData.append('size', size.value);
    formData.append('value', value.value);
    formData.append('uploadImg', img.files[0]);
profile
사람이 되고 싶은 삶은감자

0개의 댓글