Vue + ElementUI 如何优雅的上传文件到七牛OSS

  • • 发表于2018-11-06 05:30:35.0
  • • 作者 小徐同学
  • • 1441 次浏览
  • • 16 条评论
  • • 最后编辑时间 2018-12-28 04:14:38.0
  • • 来自 [笔 记]

原创声明:本文为作者原创,未经允许不得转载,经授权转载需注明作者和出处

本文的上传模式是前端直传七牛oss模式,后端只负责提供token,避免泄露accessKey

1.开通七牛OSS,创建bucket,并且实名认证,详细步骤自己看官网。传送门

2.引入七牛Java SDK

        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>[7.2.0, 7.2.99]</version>
        </dependency>

3.引入七牛Java SDK ,提供前端获取token API

    public void getToken(){
        String host = PropKit.get("qiniuHost");
        String accessKey = PropKit.get("qiniuAccessKey");
        String secretKey = PropKit.get("qiniuSecretKey");
        String bucket = PropKit.get("qiniuBucket");
        Auth auth = Auth.create(accessKey, secretKey);
        String token = auth.uploadToken(bucket);
        renderJson(RetKit.ok("token", token).set("host",host));
    }

4.Vue 安装七牛提供的sdk

npm install qiniu-js

5.Elment上传组件加入http-request参数,并且把action指向http://upload.qiniup.com/

<el-upload
      class="avatar-uploader"
      action="http://upload.qiniup.com/"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
      :before-upload="beforeAvatarUpload"
      :http-request="uploadRequest"
      >
      <img v-if="form.url" :src="form.url" class="avatar">
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>

6.编写上传JS,大体是上传的时候先向后台请求token,拿到token后调用七牛sdk直传。next 可以输出上传进度,complete上传完成。

uploadRequest: function(request) {
      getToken().then(res => {
        let token = res.token;
        let host = res.host;
        upload(
          token,
          request,
          next => {
            let total = next.total;
            console.log(total);
          },
          error => {
            console.log(error)
          },
          complete => {
            let hash = complete.hash;
            let key = complete.key;
            this.form.url = host + "/" + key;
            console.log(hash);
            console.log(key);
          }
        )
});
handleAvatarSuccess(res, file) {
      this.imageUrl = URL.createObjectURL(file.raw);
},
beforeAvatarUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
      }
      return isLt2M;
}
import * as qiniu from 'qiniu-js'
// token 找后端,obj 这里指代从 el-upload 接收到的 object
export const upload = (token, obj,next,error,complete) => {
    const {
        file
    } = obj

    // 关于 key 要怎么处理自行解决,但如果为 undefined 或者 null 会使用上传后的 hash 作为 key.
    const key = formatDate(new Date(),"yyyyMMddhhmmss") + getRandomInt(1000, 9999)

    // 因人而异,自行解决
    const putExtra = {
            fname: "",
            params: {},
            mimeType: [] || null
        },
        //       fname: string,文件原文件名
        // params: object,用来放置自定义变量
        // mimeType: null || array,用来限制上传文件类型,为 null 时表示不对文件类型限制;限制类型放到数组里: ["image/png", "image/jpeg", "image/gif"]
        config = {
            useCdnDomain: true,
            region: qiniu.region.z2
        }

    let options = {
        quality: 0.92,
        noCompressIfLarger: true,
        maxWidth: 1000,
        maxHeight: 618
    }

    qiniu.compressImage(file, options).then(data => {
        // 调用sdk上传接口获得相应的observable,控制上传和暂停
        let observable = qiniu.upload(data.dist, key, token, putExtra, config);
        let subscription = observable.subscribe(next,error,complete);
        return subscription
    }).catch(res => {
        console.log(res)
        return res
    })
}

7.附上效果视频。

评论区(共16条评论)
小徐同学
小徐同学 2018-11-09 07:36

124412341234

勇气
勇气 2018-11-17 10:34

666

Always
Always 2018-12-06 09:41

可以看源码嘛?

小徐同学
小徐同学 2018-12-07 01:08

@ Always 前端的代码都完了啊,还有疑问呀

小徐同学
小徐同学 2018-12-07 01:08

@Always

小徐同学
小徐同学 2018-12-07 01:11

@小徐同学 又发现了个bug 喵喵

Always
Always 2018-12-08 01:15

@小徐同学 可是我多张图片上传,其实是一张张上传,我怎么回调回来再上传下一张呢

小徐同学
小徐同学 2018-12-10 23:22

@Always 参考下elment ui的 upload组件 照片墙 http://element-cn.eleme.io/#/zh-CN/component/upload

prague
prague 2019-05-07 17:40

在不在?有没有这个例子的代码?急求

小徐同学
小徐同学 2019-05-07 18:25

@prague 代都贴了啊

小徐同学
小徐同学 2019-05-07 19:57

@prague 后端的代码 和前端的代码都贴在上面了,有啥问题

往事隨丶瘋
往事隨丶瘋 2019-06-06 14:32

图片上传成功后,没有触发组件原本的成功回调,这个怎么解?我需要触发成功的组件的on-success回调函数,急,,,谢谢

小徐同学
小徐同学 2019-06-06 14:47

@往事隨丶瘋 这个你得看看element的组件。 看下F12有没报错

Hope
Hope 2019-07-09 09:34

这个可以批量上传么 ?

Hope
Hope 2019-07-09 12:52

上传视频时提示unsupported file type —不支持的文件类型。。。

小徐同学
小徐同学 2019-07-10 08:52

@Hope 上传类型应该是elment控制的。本质跟后端无关

16条评论
Ctrl+Enter
作者

Michael

小徐同学

帖子:34 回复:0

全栈搬运工

作者详情》
Top