개인프로젝트
[팁] NODEJS 그리고 AWS S3 버킷생성, 파일 업로드, 파일 다운로드 기능 한번에 구현하기 - 소스코드 포함
티멀
2024. 5. 9. 16:48
728x90
반응형
소스코드
이번에 S3 처음 써보면서 NODE에 접목시키는 것에 조금 뻘짓을 좀 많이했습니다.
저같은 사람이 없길 바라며 정리해보는 글.
위에서부터 하나씩 순서대로 복붙해가면 끝이에요.
편하게 개발 고!
버킷 생성자
createBucket.js
const path = require("path");
// 이건 단순 ENV 파일 설정. 여러분 ENV 파일 맞춰서 설정해주세요
require("dotenv").config({
path: path.resolve(
__dirname,
"..",
"env",
process.env.NODE_ENV === "production" ? ".env.prod" : ".env.dev"
),
});
const AWS = require("aws-sdk");
const ACCESS_KEY = process.env.ACCESS_KEY;
const SECRET_KEY = process.env.SECRET_KEY;
const BUCKET_NAME = process.env.BUCKET_NAME;
const s3 = new AWS.S3({ accessKeyId: ACCESS_KEY, secretAccessKey: SECRET_KEY });
const params = {
Bucket: BUCKET_NAME,
CreateBucketConfiguration: {
// Set your region here
LocationConstraint: process.env.LocationConstraint,
},
};
module.exports = s3;
파일 업로드
uploadFile.js
const fs = require("fs");
const path = require("path");
require("dotenv").config({
path: path.resolve(
__dirname,
"..",
"env",
process.env.NODE_ENV === "production" ? ".env.prod" : ".env.dev"
),
});
const uploadFile = (s3, file, fileName) => {
const params = {
Bucket: process.env.BUCKET_NAME,
Key: fileName, // File name you want to save as in S3
Body: file,
// ContentType: "image/png"
};
s3.upload(params, function (err, data) {
if (err) {
throw err;
}
// console.log(`File uploaded successfully. ${data.Location}`);
});
};
module.exports = uploadFile;
// uploadFile(s3, './assets/test.png', 'testupded.png')
파일 다운로드
여기서 파일을 다운로드 받을 때 저는 db에 저장된 유니크 값을 가지고 파일을 조회한 후 지정한 파일 이름으로 다운받게 코드를 짜놨습니다.
더 효율적인 방법 있으면 댓글좀 ㄳㄳ
downloadFile.js
const path = require("path");
require("dotenv").config({
path: path.resolve(
__dirname,
"..",
"env",
process.env.NODE_ENV === "production" ? ".env.prod" : ".env.dev"
),
});
const downloadFile = (s3, dbFileName, downloadFileName, res) => {
const params = {
Bucket: process.env.BUCKET_NAME,
Key: dbFileName, // File name you want to save as in S3,
// Expires: 3600, // URL expires in 1 hour (adjust as needed)
};
s3.getObject(params, (err, data) => {
if (err) {
console.error(err);
return res.status(500).send("Error downloading file");
}
res.set({
"Content-Disposition": `attachment; filename="${downloadFileName}"`,
"Content-Type": data.ContentType,
});
res.send(data.Body);
});
};
module.exports = downloadFile;
// downloadFile("../../uploads/test-download.txt");
사용법
node 서버 내 선언
server.js OR index.js (여러분의 서버 index)
const s3 = require("../config/createBucket");
이제 여러분의 파일을 react에서 받아온다고 가정할 때, react는 아래처럼 blob으로 바꿔줍니다.
const uploadFileHandler = async (file, orderNum, version) => {
// 이 블롭이 point!
const blob = new Blob([file.originFileObj], { type: file.type });
const response = await axios.post(
`${process.env.REACT_APP_BACKEND_ROOT}/file/save/${file.name}/no/${orderNum}/ver/${version}`,
blob,
{
headers: {
"Content-Type": file.type,
},
}
);
console.log("response", response);
return response.data;
그리고 node에 파일 사이즈 limit이 걸려있으니까 아래 코드 넣어서 조절해줍시다.
app.use(
express.json({
limit: "500mb",
})
);
app.use(
express.urlencoded({
limit: "500mb",
extended: false,
})
);
app.use(bodyParser.raw({ type: "*/*", limit: "500mb" }));
받은 blob파일은 아래 node 통해서 업로드하면 됩니다.
router.post("/save/:fileName/no/:orderNum/ver/:version", async (req, res) => {
try {
const fileBuffer = Buffer.from(req.body);
uploadFile(s3, fileBuffer, 'S3에 저장할 파일 이름');
res.status(200).json(true);
} catch (error) {
console.log("er", error);
logger.error("error", error);
res.status(500).json({ error: error });
}
});
이젠 다운로드!
노드쪽에서는
router.post("/download", async (req, res) => {
const { fileName, fileDBName } = req.body;
// fileName은 다운로드 받고 난 후 저장할 파일이름이고
// fileDBName은 현재 S3에 저장된 실제 파일이름이여야함 -> OBJECT KEY값이라고 보면 됨
downloadFile(s3, fileDBName, fileName, res);
});
REACT쪽에서는
이렇게 요청하면 끝입니다!
const downloadFile = async (fileName, fileDBName) => {
const data = { fileName: fileName, fileDBName: fileDBName };
const response = await axios.post(
`${process.env.REACT_APP_BACKEND_ROOT}/file`,
data,
{ responseType: "blob" }
);
const url = window.URL.createObjectURL(response.data);
// Create an <a> element to trigger the download
const a = document.createElement("a");
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
};
참, 이거 만들려고 한 3시간은 뻘짓한거 같은데, 여러분은 좀 편하게 개발하면 좋으실 것 같아서 올려봐요!
즐코딩
728x90
반응형