아하
검색 이미지
생활꿀팁 이미지
생활꿀팁생활
생활꿀팁 이미지
생활꿀팁생활
듬직한담비100
듬직한담비10020.01.23

저장공간의 파일위치(filePath)를 알고있는데 이걸 s3 업로드할수있어요?

브라우저에서 파일업로드는 구현완료한 상태입니다.

서버단에서 파일을 생성하고 서버단의 파일위치는 알고있으니 그걸 s3에 업로드 하고싶어요

관련 링크, 함수명이라도 알려주시면 감사해요

const url; fs.createReadStream(filePath).on('data', (chunk => { buffer = chunk; s3.putObject({ Bucket: bucketName, Key: fileFullName, Body: buffer, }); url = s3.getSignedUrl('getObject', { Bucket: bucketName, Key: fileFullName, }); })); //이렇게 보내서 성공은 했지만 on event 내에서 getSignedUrl불러야 하는 상태입니다...

getSignedUrl을 on 이벤트 밖에서 사용하면 되지않냐라고 하실수있는데 함수안에 내용을 간단히 가져온거입니다...

그래서 결론적으론 filePath로 s3업로드 가능한 함수를 알려주시면 감사합니다.

55글자 더 채워주세요.
답변의 개수
1개의 답변이 있어요!
  • 안녕하세요

    일단 서버단에 업로드를 하고 해당 파일을 S3로 업로드를 시키면 매 업로드당 서버에 하나 S3에 하나로

    중복되는 파일이 생깁니다. 추천드리고 싶은 방법은 업로드시에 파일을 서버에 저장하지 않고 S3로 바로 업로드 시키는 방법이 더 효율적으로 보입니다.

    일단, 코드로..

    코드 출처 : https://docs.aws.amazon.com/ko_kr/sdk-for-javascript/v2/developer-guide/s3-example-creating-buckets.html

    s3_upload.js 라는 파일입니다.

    // Load the AWS SDK for Node.js var AWS = require('aws-sdk'); // Set the region AWS.config.update({region: 'REGION'}); // Create S3 service object s3 = new AWS.S3({apiVersion: '2006-03-01'}); // call S3 to retrieve upload file to specified bucket var uploadParams = {Bucket: process.argv[2], Key: '', Body: ''}; var file = process.argv[3]; // Configure the file stream and obtain the upload parameters var fs = require('fs'); var fileStream = fs.createReadStream(file); fileStream.on('error', function(err) { console.log('File Error', err); }); uploadParams.Body = fileStream; var path = require('path'); uploadParams.Key = path.basename(file); // call S3 to retrieve upload file to specified bucket s3.upload (uploadParams, function (err, data) { if (err) { console.log("Error", err); } if (data) { console.log("Upload Success", data.Location); } });

    위의 코드를 실행하려면,

    >> node s3_upload.js <파일이름>

    실행시에 입력한 <파일이름> 부분이 s3_upload 에서 3번째 argv 로 넘어온다고 생각하시면 됩니다.

    저위의 코드를 살짝 변경하셔서 argv에서가 아닌 현재 filePath 를 입력하셔서 파일을 읽어서 S3 로 업로드 하시면 원하시는 코드가 되겠죠?

    하지만 위에서 말씀드린것처럼 업로드 시에 로컬에 저장하기보다 바로 S3로 업로드하는 방식도 가능합니다. 밑에 내용은 웹페이지에서 바로 S3로 업로드 하는방법입니다. 필요없으시면 위의 방법을 이용하세요.

    제가 햇었던 방식은 파일 업로드 시에 base64 로 파일데이터를 읽어오는데, 해당 base64 데이터를 바로 s3 로 업로드하는 방식이 있습니다.

    코드 출처 : https://stackoverflow.com/questions/7511321/uploading-base64-encoded-image-to-amazon-s3-via-node-js

    var AWS = require('aws-sdk'); AWS.config.loadFromPath('./s3_config.json'); var s3Bucket = new AWS.S3( { params: {Bucket: 'myBucket'} } ); buf = new Buffer(req.body.imageBinary.replace(/^data:image\/\w+;base64,/, ""),'base64') var data = { Key: req.body.userId, Body: buf, ContentEncoding: 'base64', ContentType: 'image/jpeg' }; s3Bucket.putObject(data, function(err, data){ if (err) { console.log(err); console.log('Error uploading data: ', data); } else { console.log('succesfully uploaded the image!'); } });

    위의 코드 같은 방식으로 (당연히 세부적인건 사용에 맞추어서 변경하셔야 됩니다) 저렇게 하려면 웹 페이지에서 읽어온 파일을 base64로 넘겨주어야 하는데 이럴때는 적절한 라이브러리를 사용합니다.

    제가 예전에 한 방법은 dropzone.js 라는 라이브러리입니다. 처음 사용하시려면 조금 학습이 필요할 수 있습니다만, 워낙 예제들을 친절하게 많이 제공하고 있어서 무리없이 사용하실수 있을듯 합니다.

    https://www.dropzonejs.com/

    결국 정리하면,

    1. 웹페이지에 dropzone.js 적용

    2. 웹페이지의 form 완료버튼(혹은 저장버튼)을 누르면 dropzone 에서 upload 시 가지고 있던 base64 데이터를 서버의 upload url 로 전송

    3. 서버에서 받은 데이터를 위의 예시 코드로 적용

    4. S3 업로드.

    끝.

    보통 이런식이고, 서버에서는 데이터베이스나 Redis 같은곳에 해당 사용자의 S3 파일 path들을 저장해두었다가, 다시 파일들이 필요할때 페이지 S3 url 주소만 내려주는식으로 해서 처리합니다.

    수고하세요~

    이게 몇번해보면 쉬운데... 처음 하시려면 조금 복잡하고 여러번 해보셔야 될수도 있습니다.

    [팁] 2번째 S3 업로드 코드에서 replace 부분이 진짜 필수 입니다. 이게 일반적인 웹에서 읽어오는 base64 형식이 s3 에서 받는 base64와 조금 달라서 저 작업을 꼭 해줘야됩니다. 저거때문에 엄청 삽질했던 기억이....