oss上传文件遇到的坑

1.如果"ali-oss"版本为6.0以上,那么我们在使用multipartUpload分片上传会遇到很多坑。
比如:上传的文件只能小于100kb,否则上传失败,此时我们要对OSS添加useFetch: true可以完美解决,如下是我的配置

export function client(data) {
  //后端提供数据
  return new OSS({
    region: "oss-cn-hangzhou",
    accessKeyId: data.accessKeyId,
    accessKeySecret: data.accessKeySecret,
    useFetch: true, //支持上传大于100KB的文件
    secure: true, //使用https上传
    bucket: "resdev",
    stsToken: data.stsToken,
    refreshSTSToken: async () => {
      const info = await this.$api.getUploadConfig();
      return {
        accessKeyId: info.data.accessKeyId,
        accessKeySecret: info.data.accessKeySecret,
        stsToken: info.data.stsToken,
      };
    },
    refreshSTSTokenInterval: 300000,
  });
}

如下是完整的代码,上传文件组件.我用的是vant框架

<template>
  <div>
    <van-uploader
      v-model="fileList"
      :before-read="beforeUpload"//上传前调用的方法
      :after-read="Upload"//上传后调用的方法
      :before-delete="beforeDelete"//删除之前调用的方法
      @delete="deleteHandler"//删除图片时调用的方法
      accept="image/*,.doc,.docx,.pdf,.ppt" //可以接受的图片格式
      :max-size="100 * 1024 * 1024"//限制图片大小
      :max-count="fileCount"//最大上传数量,从父组件传递
      multiple//支持多文件上传
    />
  </div>
</template>
<script>
const OSS = require("ali-oss");
const uuid = require("uuid");

export function client(data) {
  //后端提供数据
  return new OSS({
    region: "oss-cn-hangzhou",
    accessKeyId: data.accessKeyId,
    accessKeySecret: data.accessKeySecret,
    useFetch: false, //android上传大于100M
    secure: true, //使用https
    bucket: "resdev",
    stsToken: data.stsToken,
    refreshSTSToken: async () => {
      const info = await this.$api.getUploadConfig();
      return {
        accessKeyId: info.data.accessKeyId,
        accessKeySecret: info.data.accessKeySecret,
        stsToken: info.data.stsToken,
      };
    },
    refreshSTSTokenInterval: 300000,
  });
}

export default {
  props: ["imgUrl", "imageMax", "urlPath", "listType", "tag", "fileCount"],
  data() {
    return {
      loading: false,
      imageUrl: [],
      dataObj: {}, //存签名信息
      baseAli: "oss-cn-hangzhou.aliyuncs.com", //后面连接图片url用的,根据自己aili OSS 配制修改
      previewVisible: false,
      previewImage: "",
      isvideo: 0,
      deleteList: [], //删除的图片,再提交时删除
      client: function () {},
      tempCheckpoint: "",
      delImgUrl: [],
      upImgUrl: [],
      fileList: [],
      fileListUpload: [],
    };
  },
  mounted() {},
  methods: {
  //上传前配置
    async beforeUpload(file) {
      return new Promise((resolve, reject) => {
        let arr = [];
        if (!file[0]) {
          arr.push(file);
        } else {
          arr = file;
        }
        for (let i = 0; i < arr.length; i++) {
          let maxSize = 20;
          const isLimitSize = arr[i].size / 1024 / 1024 < maxSize;
          if (!isLimitSize) {
            this.$toast("文件不能超过" + maxSize + "MB!");
            reject();
          }
        }
        this.$api
          .getUploadConfig()
          .then((response) => {
            this.dataObj = response.data;
            resolve();
          })
          .catch((err) => {
            this.$dd.device.notification.alert({
              message: err,
              buttonName: "确定",
            });
            reject();
          });
      });
    },
//上传
    async Upload(file) {
      const that = this;
      let arr = [];
      if (!file[0]) {
        arr.push(file);
      } else {
        arr = file;
      }
      for (let i = 0; i < arr.length; i++) {
        arr[i].status = "uploading";
        arr[i].message = "上传中...";
        let filetype = arr[i].file.type.substring(
          arr[i].file.type.indexOf("/") + 1
        );
        const fileName = that.urlPath + uuid.v4() + "." + filetype;
        await client(that.dataObj)
          .multipartUpload(fileName, arr[i].file})
          .then((result) => {
            alert("成功");
            if (result.res.status == 200) {
              arr[i].status = "success";
              arr[i].message = "上传成功";
              let fileurlArr = result.res.requestUrls[0].split("?");
              let fileInfo = {
                tag: that.tag, //文件标签名称
                fileName: result.name.substring(result.name.indexOf("/") + 1), //文件名称
                sourceName: arr[i].file.name, //原始文件名称
                filePath: fileurlArr[0], //文件路径
                contentType: arr[i].file.type.substring(
                  arr[i].file.type.indexOf("/") + 1
                ), //文件类型
                size: arr[i].file.size.toString(), //文件大小
              };
              return fileInfo;
            } else {
              arr[i].status = "failed";
              arr[i].message = "上传失败";
            }
          })
          .then((res) => {
            that.$api
              .uploadFile(res)
              .then((resdata) => {
                let url = {
                  ids: resdata.data.id,
                  name: resdata.data.fileName,
                  filename: resdata.data.sourceName,
                };
                that.upImgUrl.push(url);
                that.fileListUpload.push(url);
                that.$emit("finishUpload", that.fileListUpload);
              })
              .catch((err) => {
                this.$dd.device.notification.alert({
                  message: err,
                  buttonName: "确定",
                });
              });
          })
          .catch((err) => {
            alert(err);
            alert("失败");
            arr[i].status = "failed";
            arr[i].message = "上传失败";
          });
      }
    },
//删除前
    async beforeDelete(file) {
      let that = this;
      that.delImgUrl = [];
      let fileName = file.file.name;
      return await new Promise((resolve, reject) => {
        that
          .$confirm({ message: "是否确认删除当前图片", title: "删除提示" })
          .then(() => {
            this.$api
              .getUploadConfig()
              .then((response) => {
                this.dataObj = response.data;
                let delimg = that.upImgUrl.filter((item) => {
                  return item.filename == fileName;
                });
                delimg[0].filepathname = "restms/" + delimg[0].name;
                that.delImgUrl.push(delimg[0]);
                resolve();
              })
              .catch((err) => {
                reject();

                this.$dd.device.notification.alert({
                  message: err,
                  buttonName: "确定",
                });
              });
          })
          .catch((err) => {
            this.$dd.device.notification.alert({
              message: err,
              buttonName: "确定",
            });

            reject();
          });
      });
    },
    async deleteHandler() {
      const that = this;
      let delfile = await that.delImgUrl.map((item) => {
        return item.filepathname;
      });
      try {
        let result = await client(that.dataObj).deleteMulti(delfile);
        if (result.res.status == 200) {
          let imgid = that.delImgUrl[0].ids;
          that.$api
            .delUploadFile({ ids: that.delImgUrl[0].ids })
            .then((res) => {
              if (res.data.count == 1) {
                let del_index;
                for (let i = 0; i < that.fileListUpload.length; i++) {
                  if (imgid == that.fileListUpload[i].ids) {
                    del_index = i;
                  }
                }
                that.fileListUpload.splice(that.fileListUpload[del_index], 1);
                that.$emit("finishUpload", that.fileListUpload);
                that.$toast("删除成功!");
              } else {
                that.$toast("图片不存在!");
              }
            })
            .catch((err) => {
              console.log(err, "err");
            });
        }
      } catch (e) {
        this.$toast("删除失败!");
        console.log(e, "删除失败");
      }
    },
  },
  watch: {
    imgUrl: {
      handler(val) {
        if (val) {
          this.$set(this, "fileList", val);
        }
      },
      immediate: true,
    },
  },
};
</script>

在父组件中调用:

<template>
  <div>
    <upload-file urlPath="restms/" tag="ACN-contract" fileCount="6" @finishUpload="getImgList"></upload-file>
  </div>
</template>
<script>
import uploadFile from "@/components/upload.vue";
export default {
  name: "uploadimg",
  components: {"upload-file": uploadFile,"upload-file1": uploadFileF},
  data() {
    return {};
  },
  methods:{
    getImgList(x){
      console.log("父组件获取列表",x)
    },

  }
};
</script>

注:
我做的项目在钉钉微应用,现在有个大坑是在钉钉IOS端,无法上传文件,IOS中的浏览器是可以上传的,但是钉钉微应用里面就是不行,安卓可以完美实现上传,经过两日苦战,发现IOS不支持multipartUpload,此时我把multipartUpload改为put方法,完美解决!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值