前言
前端使用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"
]
}
]