VUE图片上传阿里oss

前言:

OSS的优势可以存放大量静态文件,如果我们用的是硬盘空间比较小的ecs或虚拟主机,就可以考虑使用OSS产品,对大部分个人/企业用户来讲OSS存储安全,可以承受大并发下的上传服务对象存储具有多重冗余架构设计;且基于高可用架构设计,消除单节点故障,跨数据中心的副本冗余,能够保障服务的高可用性,确保数据业务的持续性。

1.安装依赖

npm install ali-oss


2.配置oss上传所需要的参数

const authTemps = () => {
      authTemp()
      .then((res) => {
      state.ossClient = new OSS({
            accessKeyId: res.data.accessKeyId,
            accessKeySecret: res.data.accessKeySecret,
            stsToken: res.data.token,
            bucket: res.data.bucketName,
          });
          state._uploadUrl = res.data.uploadUrl;
        })
        .catch((err) => {
          console.log(err);
        });
    };

 onMounted(() => {
      authTemps();
  });

由后端接口获取,上传之前应该先准备好,我这里是放在mounted里面调用的

2.书写上传页面

 <el-upload
       v-model:file-list="fileList"
       class="upload-demo"
       :action="uploadUrl"
       :on-success="handlUploadsuccess"
       :http-request="ossUploadFileHandle"
       :multiple="false"
       :headers="uploadHeader"
       list-type="picture"
       accept=".png, .jpg, .jpeg"
       :show-file-list="false"
       >
    <el-button type="primary" class="buttonUpdate">
          <el-icon class="el-icon--right"> <Upload /> </el-icon>上传头像
    </el-button>
 </el-upload>

3.上传逻辑处理


//自定义上传
const ossUploadFileHandle = (file) => {
      ossUploadFile(file, 'head_logo').then((res) => {
        state.sss = res.data.relativePath;
        state.profilePhotoPath = res.data.absolutePath;
 });
};
 const ossUploadFile = (params, type) => {
      return new Promise((res) => {
        const file = params.file;
        const storeAs =state._uploadUrl + file.uid +
        file.name.substr(file.name.lastIndexOf("."));
        state.fileName = file.name;
        //分片上传oss
        state.ossClient
          .multipartUpload(storeAs, file)
          .then((results) => {
            res(results.name);
          })
          .catch((err) => {
            console.log(err);
             ElMessage.success("文件上传失败");
          });
      }).then((relativePath) => {
        // 一般的话直接上传成功就可以了,我这边的逻辑还需把oss返回的值在掉一个存储
          临时路径的方法,调用成功之后拿到临时路劲进行保存
        return tempFormal({ relativePath, serveCode: type });
      });
  };
// 上传成功的方法
    const handlUploadsuccess = (response) => {
      console.log(response);
      if (response.code === '0') {
        ElMessage.success('文件上传成功');
      } else {
        // 上传失败的处理
      }
};

4.完整代码

html:
<div class="edituserInfo" v-else>
        <div class="edituserInfo-left">
          <img
            :src="profilePhotoPath"
            alt=""
            v-if="profilePhotoPath"
            style="border-radius: 50%; width: 100px; height: 100px"
          />
          <img
            :src="userinfoData.profilePhotoPath"
            alt=""
            v-else-if="userinfoData.profilePhotoPath"
            style="border-radius: 50%; width: 100px; height: 100px"
          />
          <img
            v-else
            src="../../assets/img/avater.png"
            alt=""
            style="border-radius: 50%; width: 100px; height: 100px"
          />
          <el-upload
            v-model:file-list="fileList"
            class="upload-demo"
            :action="uploadUrl"
            :on-success="handlUploadsuccess"
            :http-request="ossUploadFileHandle"
            :multiple="false"
            :headers="uploadHeader"
            list-type="picture"
            accept=".png, .jpg, .jpeg"
            :show-file-list="false"
          >
            <el-button type="primary" class="buttonUpdate">
              <el-icon class="el-icon--right"> <Upload /> </el-icon>上传头像
            </el-button>
          </el-upload>
        </div>

js:data数据
setup(){
   fileList: [],
   uploadUrl:'',
   profilePhotoPath:'',
   uploadHeader: {},
   ossClient:null
} 
js:方法
const authTemps = () => {
      authTemp()
      .then((res) => {
      state.ossClient = new OSS({
            accessKeyId: res.data.accessKeyId,
            accessKeySecret: res.data.accessKeySecret,
            stsToken: res.data.token,
            bucket: res.data.bucketName,
          });
          state._uploadUrl = res.data.uploadUrl;
        })
        .catch((err) => {
          console.log(err);
        });
    };

 onMounted(() => {
      authTemps();
  });
//自定义上传
const ossUploadFileHandle = (file) => {
      ossUploadFile(file, 'head_logo').then((res) => {
        state.sss = res.data.relativePath;
        state.profilePhotoPath = res.data.absolutePath;
 });
};
 const ossUploadFile = (params, type) => {
      return new Promise((res) => {
        const file = params.file;
        const storeAs =state._uploadUrl + file.uid +
        file.name.substr(file.name.lastIndexOf("."));
        state.fileName = file.name;
        //分片上传oss
        state.ossClient
          .multipartUpload(storeAs, file)
          .then((results) => {
            res(results.name);
          })
          .catch((err) => {
            console.log(err);
             ElMessage.success("文件上传失败");
          });
      }).then((relativePath) => {
        // 一般的话直接上传成功就可以了,我这边的逻辑还需把oss返回的值在掉一个存储
        // 临时路径的方法,调用成功之后拿到临时路劲进行保存
        return tempFormal({ relativePath, serveCode: type });
      });
  };
// 上传成功的方法
    const handlUploadsuccess = (response) => {
      console.log(response);
      if (response.code === '0') {
        ElMessage.success('文件上传成功');
      } else {
        // 上传失败的处理
      }
};
// 获取请求头(根据自己的逻辑存取)
 const accessToken = getToken.value;
      state.uploadHeader = {
        Authorization: `Bearer ${accessToken}`,
};
axios(看需求,我这里是oss成功之后需要在调一次后端提供的临时路径进行二次存储的)
export function tempFormal(data) {
  return request({
    url: '/operation/file/upload/temp2formal',
    method: 'post',
    data
  });
}

5.oss常见上传分为分片上传和直传(上面使用的是分片上传)

OSS(Object Storage Service)是阿里云提供的对象存储服务,可以用于存储和管理大量的非结构化数据,如图片、视频、文档等。

在OSS中,分片上传和直传是两种不同的上传方式,它们有以下区别:

1. 分片上传(Multipart Upload):将大文件分割成多个小的数据块(分片),并并发地上传这些分片到OSS服务器。分片上传适用于上传大文件,可以提高上传速度和稳定性。分片上传还支持断点续传,即在上传过程中出现异常或中断后,可以从断点处继续上传,而不需要重新上传整个文件。

2. 直传(Put Object):直接将整个文件一次性上传到OSS服务器。直传适用于上传小文件或者网络条件较好的情况下,可以简化上传过程,减少上传时间。

总结来说,分片上传适用于大文件上传,可以提高上传速度和稳定性,并支持断点续传;而直传适用于小文件上传或者网络条件较好的情况下,可以简化上传过程。

在实际应用中,可以根据文件大小和网络条件选择适合的上传方式。对于大文件,建议使用分片上传;对于小文件,直传可能更加方便快捷。

 7.直传代码

 // 图片直传oss
    async afterRead(file, index) {
      const client = new OSS({
        accessKeyId: this.allOssData.accessKeyId,
        accessKeySecret: this.allOssData.accessKeySecret,
        bucket: this.allOssData.bucketName,
        stsToken: this.allOssData.token
      });
      try {
        // 直传使用client.put方法进行上传
        // 注意点:上传方法接收的两个参数(第一个就是上传的到oss上的那个路劲下面要加上唯一的文件名,不然会找不到)
        // 注意点:上传方法接收的两个参数(第二个就是你要上传的file文件)
        const result = await client.put(
          this.allOssData.uploadUrl +
            this.generateRandomId() +
            '.' +
            file.file.name,
          file.file // 使用vant需要取里层的file,原生input不需要
        );
        this.topicData[index].fileList[0].name = result.name;
        Toast('上传成功');
        console.log(this.topicData, 'this.topicData');
        this.$forceUpdate();
      } catch (e) {
        console.error('上传失败:', e);
        Toast.fail('上传失败');
      }

注意点:

上传方法接收的两个参数,第一个就是上传的到oss上的那个路劲下面要加上唯一的文件名(如下图就是后端返回的oss上传路径),不然会找不到,第二个就是你要上传的file文件。

 上传成功之后oss会给你返回一个对象,这里与分片上传是一样的,拿到需要的字段,提交给后端即可。

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值