웹에서 파일 업로드는 두 가지 방식이 있다.
(1) applecation/x-www-urlencoded
(2) multipart/form-data
전자의 경우 인코딩으로 인한 성능 이슈가 발생할수 있으니 후자의 방법으로 전송하는 것이 좋다고 한다.
DB에 이미지 저장 방법 2가지
(1) blob type으로 저장한다.
(2) 이미지 파일을 별도 폴더에 저장하고 경로명을 문자열 type으로 저장한다.
여기서는 (2) 이미지 파일을 별도 폴더에 저장하는 방법으로 진행한다. (먼저는 프로젝트 폴더 내 /uploads 폴더에 넣어보다. 배포시에는 우분투 서버내 지정된 폴더에 넣는 방법을 진행한다.)
html의 form 데이터로 이미지를 불러오는 경우
multer라는 모듈을 이용하여 파일을 받아온다.
(multer 옵셥에서는 이미지를 파일(DiskStorage)로 받거나 메모리(MemoryStorage)로 받는 경우를 설정할 수 있다.)
https://www.npmjs.com/package/multer
const express = require('express')
const multer = require('multer')
const upload = multer({ dest: 'uploads/' })
const app = express()
app.post('/profile', upload.single('avatar'), function (req, res, next) {
// req.file is the `avatar` file
// req.body will hold the text fields, if there were any
})
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})
const cpUpload = upload.fields([{ name: 'avatar', maxCount: 1 }, { name: 'gallery', maxCount: 8 }])
app.post('/cool-profile', cpUpload, function (req, res, next) {
// req.files is an object (String -> Array) where fieldname is the key, and the value is array of files
//
// e.g.
// req.files['avatar'][0] -> File
// req.files['gallery'] -> Array
//
// req.body will contain the text fields, if there were any
})
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
cb(null, file.fieldname + '-' + uniqueSuffix)
}
})
const upload = multer({ storage: storage })
upload = multer({storage}) 이 부분이 저장되는 함수라 보여진다. 이 것을 app.post()부분에서 호출해 줌으로 처리 되는듯하다.
아래 upload = multer({dest:...} 를 보면 여기는 경로만 지정해서 저장하는 방법이다. 이렇게 되면 파일이 ce243370b74107493fea0743d249a176 처럼 이상한 이름으로 확장자도 붙어 있지 않을 수 있다. 보안상 의도된 것으로 보인다.
storage 속성을 사용해서 파일명과 확장자를 사용할 수 있다.
const multer = require("multer");
const handleError = (err, res) => {
res
.status(500)
.contentType("text/plain")
.end("Oops! Something went wrong!");
};
const upload = multer({
dest: "/path/to/temporary/directory/to/store/uploaded/files"
// you might also want to set some limits: https://github.com/expressjs/multer#limits
});
app.post(
"/upload",
upload.single("file" /* name attribute of <file> element in your form */),
(req, res) => {
const tempPath = req.file.path;
const targetPath = path.join(__dirname, "./uploads/image.png");
if (path.extname(req.file.originalname).toLowerCase() === ".png") {
fs.rename(tempPath, targetPath, err => {
if (err) return handleError(err, res);
res
.status(200)
.contentType("text/plain")
.end("File uploaded!");
});
} else {
fs.unlink(tempPath, err => {
if (err) return handleError(err, res);
res
.status(403)
.contentType("text/plain")
.end("Only .png files are allowed!");
});
}
}
);
<form action="/profile" method="post" enctype="multipart/form-data">
<input type="file" name="avatar" />
</form>
참고 ::
https://www.npmjs.com/package/multer
https://intrepidgeeks.com/tutorial/node-upload-and-delete-js-images
https://velog.io/@juhyun5060/node.js-multer-sharp
https://blog.daum.net/creazier/15310525
https://eastflag.co.kr/fullstack/rest-with-nodejs/node-rest_image/
https://www.zerocho.com/category/NodeJS/post/5950a6c4f7934c001894ea83
https://handhand.tistory.com/110
좀 독특한 사이트 = 노드로 스트리밍 서버 구현
https://javafa.gitbooks.io/nodejs_server_basic/content/chapter11.html