上传图片到七牛云

1,904 阅读2分钟

流程:

  1. 七牛云后台的对象存储功能
  2. node.js后台生成七牛云的token(或者直接从服务器获取),nodeJS获取方式参考最后
<template lang="pug">
  //- 上传点击区域就可以由调用处决定
  .upload-img-to-qi-niu.full.flex.relative
    label.upload-img.full(for="inputId")
    input(ref="upload-img" id="inputId" type="file" :accept="uploadAccept" @change="handleFileChange" style="display: none")
    //- 选择图片后显示
    img.local-photo.absolute(v-if="imgSrc" :src="imgSrc")
</template>
import * as qiniu from 'qiniu-js'
export default {
  name: 'upload-img-to-qi-niu',
  props: {
    uploadAccept : {
      type: String,
      default: 'image/png,image/gif,image/jpeg,image/jpg'
    }
  },
  data() {
    return {
      imgSrc: '',
    };
  },

  methods: {
    handleFileChange() {
      const { files } = this.$refs['upload-img']
      if (!files || !files.length) {
        this.$toast('该图片不支持上传')
        return
      }
      const file = files[0]
      console.log('图片大小:'+file.size)
      // if(file.size > 1024 * 1024 * 4) {
      //   this.$toast('图片大小不能超过 4MB!')
      //   return
      // }
      const URL = window.URL || window.webkitURL;
      this.imgSrc = URL.createObjectURL(file) 

      const fileType = file.type
      console.log(fileType,'文件类型')
      
      if (this.uploadAccept.split(',').findIndex(t => t === fileType) === -1) {
        this.$toast('请上传正确的图片格式')
        return
      }
        
      this.$emit('file-change', { imgSrc: this.imgSrc ,file })
    },
	
    // 提供外部调用
    // file 
    uploadToQiNiu({ uid, sid, file}) {
      return new Promise((resolve, reject) => {
        this.getQiNiuToken(uid, sid).then(({ token, domain }) => {
          this.compressImg(file).then(dist => {
            const observable = qiniu.upload(dist,Date.now() + file.name,token,
              {
                fname: '',
                params: {},
                mimeType: null
              },
              {
                useCdnDomain: true,
                region: qiniu.region.z0
              }
            )
            // 上传开始
            observable.subscribe({
              complete(res) {
                resolve( domain + res.key)
              },
              error(err) {
                console.log('上传error: '+err)
                reject(err.message)
              }
            })

          })
        })
      })
    },
	
    // 从服务器获取七牛云token
    getQiNiuToken (uid,sid) {
      return this.$req('xxx/xxx', { uid, sid },'POST').then(res => res)
    },

    compressImg(file) {
      return new Promise((resolve,reject) => {
        const options = {
          quality: 0.92,
          noCompressIfLarger: true,
          maxWidth: 1024,
          maxHeight: 1024
        }
        return qiniu.compressImage(file, options).then(data => {
          console.log('压缩图片结果: '+ data.dist)
          resolve(data.dist)
        }).catch((err) => {
          console.log('压缩图片错误: '+ err)
          reject(err)
        })
      })
    },
  }
};
</script>

使用

import uploadImgToQiNiu from '@/components/UploadImgToQiNiu'
  .upload-box
    upload-img-to-qi-niu(@file-change="onFileChange" ref="uploadComp")
  .upload-desc 点击上传图片
onFileChange ({ file }) {
	this.file = file
},

// 上传file到七牛云换取网络地址
getImgNetWorkUrl(file) {
  return this.$refs.uploadComp.uploadToQiNiu({ uid, id,file }).then(screenshot => {
    return Promise.resolve(screenshot)
  })
},

onSummit () {
	this.getImgNetWorkUrl(this.file).then(url => {
    	this.$req('xxx/uploda-url').then(() => {})
    })
}

nodeJ生成token

  1. 注册七牛云,在个人中心---《秘钥》获取如下三个参数
// https://developer.qiniu.com/kodo/1289/nodejs
var accessKey = 'your access key';
var secretKey = 'your secret key';
var mac = new qiniu.auth.digest.Mac(accessKey, secretKey);
var options = {
  scope: bucket,
};
var putPolicy = new qiniu.rs.PutPolicy(options);
var uploadToken=putPolicy.uploadToken(mac);
其它自行查阅

归纳

  1. 通过input的file类型选择图片上传,获取图片的本地url路径file;
  2. 服务器一般只存储图片的网络地址,因此要将本地图片先上传到七牛云,换取网络地址后再将网络地址传递给服务器储存,具体步骤如下;
  3. 点击上传时,通过服务器获取七牛云存储的token,然后调用七牛云提供的上传图片的api,换取网络地址