multer,multer-3
nodejs 미들웨어로 S3는 Amazon Simple Storage Service로, 인터넷용 스토리지 서비스입니다. 쉽게 AWS에서 제공하는 파일 저장 공간이라고 생각하시면 됩니다. multer-s3를 사용하여 이미지 업로드 시 로컬 서버가 아닌 S3에 이미지를 업로드하게 됩니다.
설치
npm install multer multer-s3
설정
ImageUpload.js
const multer = require('multer');
const {v4: uuid} = require('uuid')
const mime = require("mime-types");
const multerS3 = require("multer-s3") //aws
const {s3} = require("../aws")
// const storage = multer.diskStorage({ //diskStorage 사용시 파일저장과정을 제어가능
// destination: (req,file,cb)=>cb(null, "./uploads"),
// filename:(req,file,cb)=>cb(null, `${uuid()}.${mime.extension(file.mimetype)}`), //uuid를 이용해 각파일당 고유이름 갖기(같은 파일을 올릴수도 있으므로)
// })
const storage = multerS3({ //aws에 파일저장 (upload폴더에서 aws로 변환)
s3,
bucket:"image-upload2", //버켓이름,
key:(req,file,cb)=>cb(null, `raw/${uuid()}.${mime.extension(file.mimetype)}`), //key설정 raw폴더안에 저장
});
const upload = multer({storage , fileFilter:(req,file,cb)=>{ //multer 이용한 upload , filter를 이용해 이미지저장
if(['image/jpeg' , 'image/png'].includes(file.mimetype)) cb(null,true) // true = 저장
else cb(new Error('invalid error'), false) //fasle = 저장x
},
limits:{
fileSize:1024*1024*5, //파일 사이즈 제한
},
});
module.exports = {upload} //미들웨어
aws 키가 노출되면 엄청난 요금이 청구될 수 있으니 주의.
사용
index.js
imageRouter.post('/',upload.single("image"),async function(req,res){ //포토번호 , 미들웨어(이미지 하나받기) ,실행함수 "image":key
//유저권한 확인: 미들웨어 확인 , 유저정보저장 ,public유무 확인
try{
if(!req.user) throw new Error("권한이 없습니다")//로그인x
const image = await new Image({
user:{ _id:req.user.id , name:req.user.name , username:req.user.userName}, //_id : objectID id: _id를 알아서 string으로 변환해줌 (object <->string 몽구스에서 알아서 변환해줌)
public: req.body.public, //원래 string으로 보내지만 몽구스에서 boolean으로 바꿔줌(나중에 json으로 바꿔줘야됨)
key: req.file.key.replace("raw/",""), // /raw를 빼고 빈열로 대체
originalFileName: req.file.originalname
}).save() //save = 데이터베이스에 저장하는부분 // 비동기적부분 : async 사용
res.json(image)//리턴부분
}
catch(err){
res.status(400).json({message:err.message})//400 :유저잘못입력 , 500:서버오류
console.log(err)
}
});
//single ->array로 바꿈 5는 최대장수
결과는 req.file, req.files에 저장된다.
const formData = new FormData //데이터는 보통 json으로 보내주는데 이미지파일은 formdata이용
formData.append("image", file)//key,value // 여기서 key는 백엔드의 upload.single("image") 와 동일시
formData.append("public" , isPublic)
const res = await axios.post("/images" , formData , { //경로,데이터,
headers: {"Content-Type": "multipart/form-data"}, //보내는 리소스 타입
onUploadProgress : (e) =>{ //자바스스크립트 내장함수
setPercent(Math.round((100 * e.loaded)/e.total)); //이미지 업로드시 프로그레스바 퍼센트 업데이트
},
});
프론트단에서 input 프로퍼티
enctype="multipart/form-data"를 추가하던가,
axios에이런식으로 컨텐트타입을 설정해주어야 한다.
'AWS' 카테고리의 다른 글
S3 presignedUrl 생성 , presignedUrl이용해서 S3,DB에 이미지저장 (0) | 2022.03.10 |
---|---|
s3 deleteObject (0) | 2022.03.09 |
IAM 유저생성 (0) | 2022.03.05 |
S3+CloudFront (0) | 2022.03.04 |
S3 (0) | 2022.03.04 |