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"
]
}
]