본문 바로가기
클라우드

POST 방식으로 S3 버킷에 파일 업로드 #2

by ^..^v 2020. 11. 4.
728x90
반응형

API Gateway 설정

#1 s3-policy-document 리소스 생성

 

 

#2 메소드 생성

 

 

#3 CORS 활성화

 

 

#4 API 배포

 

 

업로드 버킷 CORS 설정

[참고] docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/cors.html

 

24-Hour-Video 웹 사이트에 파일 업로드 기능 추가

[참고] docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html

C:\serverless\24-hour-video\js\upload-controller.js 파일 생성

var uploadController = {
    data: {
        config: null
    }, 
    uiElements: {
        uploadButton: null
    }, 
    init: function(configConstants) {
        this.data.config = configConstants;
        this.uiElements.uploadButton = $('#upload');
        this.uiElements.uploadButtonContainer = $('#upload-video-button');
        this.uiElements.uploadProgressBar = $('#upload-progress');
        this.wireEvents();
    }, 
    wireEvents: function() {
        var that = this;

        //  업로드 파일을 선택하면 추출한 파일명과 함께 보안정책을 생성하는 람다 함수를 호출
        this.uiElements.uploadButton.on('change', function(result) {
            var file = $('#upload').get(0).files[0];
            var requstDocumentUrl = that.data.config.getUploadPolicyApiUrl + '/s3-policy-document?filename=' + encodeURI(file.name);
            $.get(requstDocumentUrl, function(data, status) {
                console.log('s3-policy-document >>> ', data);
                that.upload(file, data, that);
            });
        });
    }, 
    //  보안정책을 요청본문에 추가해서 첨부파일과 함께 S3 버킷으로 POST 방식으로 전달
    upload: function(file, data, that) {
        this.uiElements.uploadButtonContainer.hide();
        this.uiElements.uploadProgressBar.show();
        this.uiElements.uploadProgressBar.find('.progress-bar').css('width', '0');

        var fd = new FormData();
        fd.append('key', data.key);
        fd.append('policy', data.encoded_policy);
        fd.append('acl', data.acl);
        fd.append('x-amz-algorithm', data.x_amz_algorithm);
        fd.append('x-amz-credential', data.x_amz_credential);
        fd.append('x-amz-date', data.x_amz_date);
        fd.append('x-amz-signature', data.x_amz_signature);
        fd.append('file', file, file.name);        
        $.ajax({
            url: data.upload_url,
            type: 'POST', 
            data: fd, 
            processData: false,
            contentType: false, 
            xhr: this.progress,
            beforeSend: function(req) {
                req.setRequestHeader('Authorization', '');
            }
        }).done(function(response) {
            that.uiElements.uploadButtonContainer.show();
            that.uiElements.uploadProgressBar.hide();
            alert('업로드 성공');
        }).fail(function(response) {
            that.uiElements.uploadButtonContainer.show();
            that.uiElements.uploadProgressBar.hide();
            console.error(response);
            alert('업로드 실패');
        })
    }, 
    progress: function() {
        var xhr = $.ajaxSettings.xhr();
        xhr.upload.onprogress = function(evt) {
            var percentage = evt.loaded / evt.total * 100;
            $('#upload-progress').find('.progress-bar').css('width', percentage + '%');
        };
        return xhr;
    }
}

 

c:\serverless\24-hour-video\js\config.js

var configConstants = {
  			:
    //  get-upload-policy API
    getUploadPolicyApiUrl: 'https://ytvleziy6a.execute-api.us-east-1.amazonaws.com/dev'
};

 

c:\serverless\24-hour-video\index.html

<!doctype html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang=""> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8" lang=""> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9" lang=""> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang=""> <!--<![endif]-->
    <head>
        :
    </head>
    <body>
      	:
      <!-- Main jumbotron for a primary marketing message or call to action -->
      <div class="jumbotron">
          :
        <!-- 추가 버튼과 진행 상태 출력 영역 추가 -->
        <span id="upload-video-button" class="btn btn-info btn-file">
          <span class="glyphicon glyphicon-plus"></span>
          <input id="upload" type="file" name="file">
        </span>
        <div class="progress" id="upload-progress">
          <div class="progress-bar progress-bar-info progress-bar-striped" role="progressbar" aria-valuemin="0" aria-valuemax="100"></div>
        </div>
      </div>
        :
    <footer>
      <p>&copy; Company 2015</p>
    </footer>
    </div> <!-- /container -->        
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
        		:
        <!-- upload-controller.js 파일 추가 -->
        <script src="js/upload-controller.js"></script>
        		:
    </body>
</html>

 

c:\serverless\24-hour-video\css\main.css

		:
        
#upload-video-button {
   display: none;
   margin-bottom: 30px;
}

.btn-file {
   position: relative;
   overflow: hidden;
}

.btn-file input[type=file] {
   position: absolute;
   top: 0;
   right: 0;
   min-width: 100%;
   min-height: 100%;
   font-size: 100px;
   text-align: right;
   filter: alpha(opacity=0);
   opacity: 0;
   outline: none;
   background: white;
   cursor: inherit;
   display: block;
}

#upload-progress {
   display: none;
}

#video-list-container {
   text-align: center;
   padding: 30px 0 30px;
}

.progress {
   background: #1a1a1a;
   margin-top: 6px;
   margin-bottom: 36px;
}

 

테스트

업로드 버킷 확인

 

파일 업로드

 

S3 버킷 확인

728x90
반응형

댓글