본문 바로가기

잡단한것들/코딩연습장

Node.js, FormData => multer모듈로 업로드 하기

client

document.getElementById("filepicker").addEventListener("change", e => {
    menuVal.checked = false;
 
    let output = document.getElementById("listing");
    let files = e.target.files;
 
    for (let i = 0; i < files.length; i++) {
        formData.append('uploadFiles', files[i]);
    }
 
    for (let i = 0; i < files.length; i++) {
        let item = document.createElement("li");
        item.classList.add('list-group-item');
        item.innerHTML = files[i].name;
        output.appendChild(item);
    };
});
 
document.getElementById('uploadBtn').addEventListener('click', () => {
    const config = {
        onUploadProgress: e => {
            let percentage = (e.loaded * 100/ e.total;
            let currentPercentage = Math.round(percentage);
            console.log(currentPercentage + "%");
            setProgress(currentPercentage );
        },
        headers: {
            'Content-Type''multipart/form-data'
        }
    };
 
    axios.post('http://localhost:3000/upload', formData, config)
        .then((req, res) => {
            console.log(res);
        })
        .catch(err => console.log(err));
})

server

let storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null'uploads/'); //파일 올리면 저장할 폴더 위치
    },
    filename: (req, file, cb) => {
        cb(null, `${Date.now()}_${file.originalname}`); //저장할 때 파일이름
    }
})
 
//storage생성 후
const upload = multer({ storage }).array('uploadFiles')
 
app.post('/upload', upload, (req, res) => {
    console.log(req.files);
    res.send('upload success');
})

 

프론트단에서 FormData 객체를 axios로 전송하고 서버단에서 multer모듈로 업로드 처리를 해봤다.

단일 파일 말고 폴더로 업로드 하려면 <input type="file" id="filepicker" name="fileList" webkitdirectory multiple /> webkitdirectory가 들어가야 된다.

처음에 FormData에 파일들 배열을 바로 담으면 된다고 누가 써놔서 그렇게 보냈다가 안되서 한시간 정도 삽질을 했다. 당연하게도 파일 배열 풀어서 하나씩 담아주니 잘 전송된다.

limit을 설정하지 않은 상태에서 한번에 대량의 파일을 전송하니 70여개 쯤에서 서버가 멈춘다. 아마도 메모리가 감당하지 못하는 것 같다. 다량의 파일을 한번에 전송하려고 하는데 이 방법은 적합하지 않은 것같다.

 

참고한 자료

https://developer.mozilla.org/ko/docs/Web/API/FormData

 

FormData - Web API | MDN

FormData 인터페이스는 form 필드와 그 값을 나타내는 일련의 key/value 쌍을 쉽게 생성할 수 있는 방법을 제공합니다. 또한 XMLHttpRequest.send() (en-US) 메서드를 사용하여 쉽게 전송할 수 있습니다. 인코

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/HTML/Element/Input/file#%EA%B3%A0%EC%9C%A0_%ED%8C%8C%EC%9D%BC_%EC%9C%A0%ED%98%95_%EC%A7%80%EC%A0%95%EC%9E%90

 

- HTML: Hypertext Markup Language | MDN

file 유형의

요소에는 저장 장치의 파일을 하나 혹은 여러 개 선택할 수 있습니다. 그 후, 양식을 제출해 서버로 전송하거나, File API를 사용한 JavaScript 코드로 조작할 수 있습니다.

developer.mozilla.org

https://developer.mozilla.org/ko/docs/Web/API/XMLHttpRequest/upload

 

XMLHttpRequest.upload - Web API | MDN

XMLHttpRequest upload 프로퍼티는 업로드 진행 상황을 모니터링 할 수 있는 XMLHttpRequestUpload 객체를 반환합니다.

developer.mozilla.org

 

axios에서 progress bar 구현 함수

onUploadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
}, // `onDownloadProgress` allows handling of progress events for downloads
// browser only
onDownloadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},