Vue大文件分片上传 直连AWS S3

前言

前端使用vue2+elementui2.15.6+axios0.23.0 上传文件,直连AWS S3。进度条使用elementui2.0中的progress进度条组件。

vue中安装的aws-sdk为2.235.1版本,即AWS SDK for JavaScript版本2,非最新的版本3

现存问题:版本3缺少认证Amazon cognito身份认证,所在宁夏区,无此服务。不清楚如何使用accessKeyId和secretAccessKey代替cognito直连s3上传。故使用版本2。

参考链接:

https://aws.amazon.com/cn/blogs/china/s3-multipul-upload-practice/

https://www.cnblogs.com/lyjfight/p/12942829.html

重要::虽然我很菜,写的也不够好,但我不接受任何批评,本文仅供有需要的人参考及自己记录用。

效果截图

点击文件上传按钮,选择文件,分片上传,进度条由0到100%,上传过程中,按钮禁止点击。

代码实现

安装aws-sdk

npm install aws-sdk@2.235.1

需要获取AWS的accessKeyId、secretAccessKey、region以及存储桶名称。存储桶需要配置CORS(跨资源共享)

完整代码

<template>
    <div>
        <el-button type="primary" @click="fileClick()" :loading="loading">文件上传</el-button>
        <input type="file" id="fileExport" @change="handleFileChange" ref="inputer" style="display:none">
        <p>
            <el-progress :text-inside="true" :stroke-width="26" :percentage="progress"></el-progress>
        </p>
    </div>
</template>

<script>
    var AWS = require("aws-sdk");
    export default {
        data() {
            return {
                s3: new AWS.S3({ // AWS 认证相关
                    accessKeyId: XXX,
                    secretAccessKey: XXX,
                    region: XXX
                }),
                upload: null,
                loading: false, // 防止再次点击
                progress: 0 ,// 进度条
                fileName: "", // 文件名称
                suffix: "", // 文件后缀
            }
        },
        methods: {
            fileClick: function() { // 点击button按钮click事件
                this.$refs.inputer.dispatchEvent(new MouseEvent('click')) // 触发input框的click事件
            },
            handleFileChange(e) { // 触发input选择文件事件
                var self = this;
                let inputDOM = self.$refs.inputer;
                var file = inputDOM.files[0]; // 通过DOM取文件数据
                if (file) {
                    self.loading = true;
                    self.progress = 0;
                    self.fileName = file.name;
                    self.suffix = self.fileName.split(".")[1];
                    var key = new Date().getTime() + "_" + Math.random().toFixed(2) + "." + self.suffix;
                    var params = {
                        Bucket: XXX, // 存储桶名称
                        Key: key, // 文件名,重名会覆盖
                        ContentType: file.type, // 文件类型
                        Body: file, // 具体的文件
                        'Access-Control-Allow-Credentials': '*',
                        'ACL': 'public-read'
                    };
                    self.upload = self.s3.upload(params, {
                        // queueSize: 1 // 并发数
                    }).on('httpUploadProgress', function(e) { // 进度条
                        var precent = (parseInt(e.loaded, 10) / parseInt(e.total, 10)) * 100;
                        precent = parseInt(precent.toFixed(2));
                        setTimeout(function() {
                            self.progress = precent;
                            if (precent == 100) {
                                self.loading = false;
                            }
                        }, 3000);
                    });
                    self.sendUpload();
                }
            },
            sendUpload: function() { // 上传文件
                var self = this;
                self.upload.send(function(err, data) {
                    if (err) {
                        console.log("发生错误:", err.code, err.message);
                        self.loading = false;
                    } else {
                        console.log("上传成功, 返回结果");
                        console.log(data);
                        var url = data.Location; // 文件访问地址
                    }
                })
            }
        },
    }
</script>

<style></style>

s3 存储桶CORS

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "HEAD",
            "GET",
            "PUT",
            "POST",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag",
            "x-amz-meta-custom-header"
        ]
    }
]
原文地址:https://www.cnblogs.com/aiyowei/p/15769695.html