[AWS] S3 이용하여 프로필 이미지 등록 기능 구현하기

Serin Yoon·2021년 12월 3일
2

Backend

목록 보기
5/5
post-thumbnail

프로젝트를 진행하면서 사용자가 프로필 이미지를 등록하는 기능이 필요해졌다.

이전에 AWS의 S3를 이용하여 젯슨나노가 S3에 이미지 파일과 JSON 파일을 업로드하면 lambda가 이를 감지하고 이미지 URL과 JSON 데이터를 백엔드로 전송하는 코드를 구현했는데, 이번에는 프론트단에서 S3에 이미지 파일을 업로드하면 프론트단으로 이미지 URL을 리턴해주는 과정이 필요했다.

S3에 파일을 올리면 기본적으로 이미지 URL을 포함한 업로드 정보를 리턴해주기 때문에 코드가 굉장히 간단하다.

S3 설정 과정은 https://merrily-code.tistory.com/142?category=938924 를 참고했다.


1. SDK 추가

html 코드의 head 태그 안에 AWS SDK를 추가한다.
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.891.0.min.js"></script>


2. 사진 업로드 태그, button 생성

<input type="file" accept="image/*" id="file" />
<button type="button">upload!</button>

이미지를 업로드하고, upload! 버튼을 누르면 uploadImg 함수가 실행되도록 한다.
input type을 file로 하고, accept="image/*"를 작성하면 이미지 파일 업로드만 허용된다. (참고: http://tcpschool.com/html-tag-attrs/input-accept)


3. onClick 함수

uploadImg = () => {
    AWS.config.update({
        region: 'ap-northeast-2',
        credentials: new AWS.CognitoIdentityCredentials({
            IdentityPoolId: {S3 설정시 얻은 IdentityPoolId},
        })
    })
    
    let files = document.getElementById('file').files;
    let file = files[0];
    let fileName = file.name;
    
    let upload = new AWS.S3.ManagedUpload({
        params: {
            Bucket: {S3 Bucket 이름},
            Key: fileName,
            Body: file
        }
    })
    
    const promise = upload.promise();
    promise.then(
        (data) => {
            document.getElementById('imgDiv').innerHTML = `
                <img src=${data.Location} style="width:300px; height:300px; border:1px solid black;">
            `;
        },
        (err) => {
            console.log('err >', err)
        }
    )
}

IdentityPoolId는 S3 설정할 때 확인할 수 있다. (참고: https://merrily-code.tistory.com/142?category=938924)

input 태그로 업로드한 파일과 파일명을 가져온다.

파일명은 나중에 Key값으로 설정했는데, S3 버켓에 업로드 될 때 이 Key값(파일명)이 중복되면 새로 등록되는 파일로 바뀌기 때문에 앞에 업로드 날짜를 붙이던지 해서 고유한 값으로 만드는 것이 좋다. (ex. YYYYMMDD_파일명.png) 나는 우선 파일명으로만 했다.

업로드에 성공하면 이미지 URL을 추출해서 웹상에 띄우고, 실패하면 콘솔로 에러를 출력한다.

✔ IdentityPoolId, S3 bucket 이름은 공개되지 않는 것이 안전하므로 가급적이면 env를 이용하는 것이 좋다.


4. 전체 코드

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.891.0.min.js"></script>
    <title>S3 Upload Test</title>
</head>
<body style="text-align: center;">
    <h1>S3 Upload Test</h1>
    <input type="file" accept="image/*" id="file" />
    <button type="button" onClick="uploadImg()">upload!</button>
    <br /> <br />
    <div id="imgDiv"></div>
</body>
<script>
    uploadImg = () => {
        AWS.config.update({
            region: 'ap-northeast-2',
            credentials: new AWS.CognitoIdentityCredentials({
                IdentityPoolId: {S3 설정시 얻은 IdentityPoolId},
            })
        })

        let files = document.getElementById('file').files;
        let file = files[0];
        let fileName = file.name;

        let upload = new AWS.S3.ManagedUpload({
            params: {
                Bucket: {S3 Bucket 이름},
                Key: fileName,
                Body: file
            }
        })

        const promise = upload.promise();
        promise.then(
            (data) => {
                document.getElementById('imgDiv').innerHTML = `
                    <img src=${data.Location} style="width:300px; height:300px; border:1px solid black;">
                `;
            },
            (err) => {
                console.log('err >', err)
            }
        )
    }
</script>
</html>

profile
티스토리로 이사했습니다 🏠

2개의 댓글

comment-user-thumbnail
2021년 12월 4일

잘보고 갑니다. ^^

1개의 답글