图片上传到阿里oss和下载到本地 vue

前端上传图片和下载

  1. 通过后端接口上传图片

    上传 file 对象给接口

<input type="file" ref="fileinput" name="fileContent" @input="getinfo($event)" style="display:none">
<img src="" ref="imagesss" class="showimgs" /> 
getinfo(el){
      if( this.$refs.fileinput.files.length > 0 ){
        var file = this.$refs.fileinput.files[0] // 这个就是上传到接口的file对象 
        var fileReader = new FileReader()  // FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
        fileReader.readAsDataURL(file) //将file对象读取为一段以 data: 开头的字符串,可以直接赋值给 img的src
        fileReader.onload = ()=> { 
          if (/^image/.test(file.type)) {
              // 读取结果在fileReader.result里面
              this.$refs.imagesss.src = fileReader.result //将读取的图片展示
          }
        }
        if( (5*1024*1024) >= file.size ) { //判断图片大小
          this.icon = file
        } else {
          this.$Message.warning('上传的图片不能大于 5M')
        }
      }
    },
  1. 直接上传到对象存储(oss)

    通过对接oss,直接上传图片到oss,不过有安全性问题。

<uploadimg :list.sync="list" :uploadpic="uploadpic" :violist.sync="violist" :VPflag="VPflag" :limit="limitpic" :xzflag="xzflag" :num="num" class="upload-img" />
<template>
    <div id="uploadimg">
            <el-upload
                action="''"
                list-type="picture-card"
                :http-request="uploadpic"
                :before-upload="beforeAvatarUpload"
                :on-preview="handlePictureCardPreview"
                :on-remove="handleRemove"
                :file-list="showlist"
                >
                <i class="el-icon-plus"><div style="font-size:12px;margin-top: 3px;">上传图片</div></i>
            </el-upload>
        <el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="picList" />
    </div>
</template>
<script>
//element-ui  upload修改预览功能,需安装element-ui
//说明:
//  uploadpic:父组件传入upload方法
//  list:父组件传入图片列表
//  limit:父组件传入图片大小限制
import ElImageViewer from 'element-ui/packages/image/src/image-viewer'  //查看图片
export default {
    name: 'uploadimg',
    components: { ElImageViewer },
    props: ['list','uploadpic','limit','num','xzflag'],
    data() {
        return {
            showViewer: false,
            showlist: [],
            picList: [],
        }
    },
    created() {
        this.getimgdata()
    },
    methods: {
        //获取图片列表
        getimgdata() {
            this.showlist = this.list
            for(let i in this.showlist) {
                this.picList.push(this.showlist[i].url)
            }
        },
        //点击预览图片
        handlePictureCardPreview(file) {
            this.showViewer = true
            let i = 0
            for(i=0;i<this.showlist.length;i++) {
                if(this.picList[i] == file.url)
                    break
            }
            for(let j=0;j<i;j++) {
                this.picList.push(this.picList[j])
            }
            this.picList.splice(0,i)
        },
        //删除上传图片
        handleRemove(file, fileList) {
            this.$emit('update:list',fileList)
            this.showlist = fileList
            this.picList = []
            for(let i in this.showlist) {
                this.picList.push(this.showlist[i].url)
            }
        },
        //关闭预览图片
        closeViewer() {
            this.showViewer = false
        },
        beforeAvatarUpload(file) {
            let isLt = file.size / 1024 / 1024 < this.limit
            if (!isLt) {
                this.$message.error('上传图片大小不能超过'+this.limit+'MB!')
            }
            return isLt
        },
    },
    watch: {
        //监听父组件图片列表的变化
        list(val) {
            this.showlist = val
            this.picList = []
            for(let i in this.showlist) {
                this.picList.push(this.showlist[i].url)
            }
        },
        num( val,old ){ // 控制图片个数
            var el = document.getElementsByClassName('el-upload')[0]
            var els = document.getElementsByClassName('el-upload')[1]
            var elss = document.getElementsByClassName('el-upload')[2]
            var elsss = document.getElementsByClassName('el-upload')[3]
            if( val > 8 ){
                if( this.xzflag == true){
                    elss.style.display = 'none'
                    elsss.style.display = 'none'
                } else {
                    el.style.display = 'none'
                    els.style.display = 'none'
                }
                // console.log( el )
            } else {
                if( this.xzflag == true ){
                    elss.style.display = 'inline-block'
                    elsss.style.display = 'inline-block'
                } else {
                    el.style.display = 'inline-block'
                    els.style.display = 'inline-block'
                }
            }
        }
    }
}
</script>
<style scoped>
#uploadimg >>> .el-upload-list--picture-card .el-upload-list__item-status-label {
    position: absolute;
    right: -17px;
    top: -17px;
    width: 60px;
    height: 60px;
    background: none;
    background-image: url('../../assets/images/weifabu.png');
    background-repeat: no-repeat;
    background-size: 60px 60px;
    box-shadow: 0 0 1pc 1px rgba(0,0,0,.2);
    transform:none;
}
#uploadimg >>> .el-upload-list--picture-card .el-upload-list__item-status-label i{
    display: none;
}
</style>

图片上传处理函数

// 处理上传结果并保存到数据库
    uploadpic(file) {
      // 获取文件后缀
      const tmp = file.file.name.split('.');
      const extname = tmp.pop();
      const imgextList = ['jpg', 'jpeg', 'png', 'gif'];
      const vioextList = ['AVI', 'ASF', 'MOV', 'QT','RM','NAVI','DivX','MPEG','DAT','MPG','mp4'];
      var isimg = imgextList.includes(extname) 
      var isvio =  vioextList.includes(extname)
      // 校验文件类型
      if( isimg ) {
        this.VPflag = false
      }
      if( isvio ) {
        this.VPflag = true
      }
      if ( !isimg && !isvio ) {
        this.$message.warning(`支持上传 jpg、jpeg、png、gif 格式的图片 或者  AVI、ASF、MOV、QT、RM、NAVI、DivX、MPEG、DAT、MPG、mp4 格式的视频`);
        return;
      }
      var randomName = Array(32)
          .fill(null)
          .map(() => Math.round(Math.random() * 16).toString(16))
          .join('');
      // console.log( isimg )
      var path
      if( isimg ) {
        path = `${this.username}/picture/${randomName}-${this.daili.length+1+this.list.length}.${extname}`; //上传图片的地址
      }else {
        path = `${this.username}/video/${randomName}-${this.daili.length+1+this.list.length}.${extname}`; //上传视频的地址
      }
      var type
      try {
        // 使用 multipartUpload 正式上传到 oss
        if( isimg ) {
          this.listpic.push({"image":path})
          type=0
        } else {
          this.listvio.push({"video":path})
          type=1
        }
        this.dlclient.multipartUpload(path,file.file).then((res)=>{  //使用分片上传
          if( res.res.statusCode == 200 ){
            let params = {
              image_url:path,
              type:type,
              size:file.file.size
            }
            shangchuanoss('',SaltEnp(params)).then(res=>{ 
              this.mysqlimg.push(res.data.data)
            })
            const url = this.dlclient.signatureUrl(path, { //通过 signatureUrl 得到完整的url地址
                expires: 3600, // 设置过期时间,默认为1800秒。
                method: 'GET' //  设置请求方式为PUT。默认请求方式为GET。
            });
            if( isimg ) {
              this.list.push({url:url})
            } else {
              this.violist.push({url:url})
            }
          } else {
            this.$Message.error('上传oss失败')
          }
        });
      } catch (error) {
        this.$message.error(`${error}`);
      }
    },
//得到oss 对象
    getossinfo(){
      var params = {
        "source": "web",
        "type": "sts",
      }
      GetstsDevice('',SaltEnp(params)).then(res=>{ //通过后端接口,获取oss所需的参数
        if ( res.data.code === 1) {
          var info = res.data.data
          this.expirationTime = this.formateDate(info.Expiration); //过期时间
          //代理的oss
          this.dlclient = new OSS({ //获取client对象
            accessKeyId:info.AccessKeyId, 
            accessKeySecret:info.AccessKeySecret, 
            stsToken:info.SecurityToken,
            region: '*******',
            bucket: '*******'
          });
        }
      });
    }

下载oss对应文件的图片

on: {
   click:()=>{
      const result = this.client.list({ // 通过client.list,列举想要的文件下的对象,得到promise对象
      	prefix: `${this.sid}/picture/${params.row.dirname}/`,
        delimiter: '/'
      });
      result.then(res=>{ 
         res.objects.forEach(obj => {
             this.downloadFile(obj.name)  //调用图片下载函数
             // let result = this.client.signatureUrl(`${obj.name}`); //通过 signatureUrl 方法获得完整下载地址
             // location.href= result
             // console.log( result ) 
         });
      })
       }
 }


// 批量下载oss对象里面的图片,使用 location,只能下载最后一张,原因:图片还未下载完毕,就跳转, 使用onload。
    downloadFile(key) {
      // console.log(key)
      if( key.lastIndexOf('.')!= -1 ){
        var imgtype = key.substr(key.lastIndexOf('.')+1,key.length)  //判断是什么格式的图片
      }
      let url = this.client.signatureUrl(key); //获取完整地址
      let Img = new Image(), dataURL = '';
      // let fileName = key.substring(key.indexOf('_')+1); //文件下载下来的名字
      let fileName = key;
      Img.src = url;
      Img.setAttribute("crossOrigin", 'Anonymous'); // 设置跨域
      Img.onload = function () { //要先确保图片完整获取到,这是个异步事件
        let canvas = document.createElement("canvas"), //创建canvas元素
        width = Img.width, //确保canvas的尺寸和图片一样
        height = Img.height;
        canvas.width = width;
        canvas.height = height;
        canvas.getContext("2d").drawImage(Img, 0, 0, width, height); //将图片绘制到canvas中
        if( imgtype == 'png' ){
          dataURL = canvas.toDataURL('image/png'); //转换图片为对应的dataURL
        } else {
          dataURL = canvas.toDataURL('image/jpeg'); //转换图片为对应的dataURL
        }
        let eleLink = document.createElement('a');
        eleLink.download = fileName;
        eleLink.style.display = 'none';
        eleLink.href = dataURL;
        document.body.appendChild(eleLink);
        eleLink.click();
        document.body.removeChild(eleLink);
      };
    },
  1. 上传到七牛云

通过对接七牛云,直接上传图片到七牛云,不过也有安全性问题。处理图片函数中,这里控制了图片大小小于4M,如果图片大于4M,使用这个方法会存在问题。 我这里使用了 ‘qiniu-js’ 插件。使用之前需要导入, import * as qiniu from ‘qiniu-js’。 具体参考 七牛云js-sdk文档

<input type="file" ref="fileinputs" name="fileContent" @input="getinfos" style="display:none">
getinfos(){ 
      if( this.$refs.fileinputs.files.length > 0 ){
        if( this.detailimgobj.length<5 ){ //控制图片数量
          var file = this.$refs.fileinputs.files[0] //这个就是第一种方法中,获取file对象
          if( (4*1024*1024) >= file.size ) {  //控制图片大小,这里控制了图片大小小于4M,如果图片大于4M,使用这个会有问题
            // 图片上传到七牛云上
            let config = {
              "AK":"M0zHAZqlEfVYZYqanOCaQLvuDYWKgtwtZJpHHiWv",
              "SK":"01MUPfns2TtpqqTcz5HVaap-XcYzdtFFGJmBhzJF",
              "Bucket":"media"
            }
            var putExtra = {
                fname: "",
                params: {},
                mimeType:["image/png", "image/jpeg", "image/gif"]
            };
            var observable = qiniu.upload(file, new Date().getTime() , this.qiniuyuntoken, putExtra, config)  
            var _this = this
            var subscription = observable.subscribe({ 
              next(res){
              },
              error(err){
                this.$Message.error('文件已经存在')
              },
              complete(res){ 
                var obj = {}
                obj.url = '七牛云的基础地址'+res.key  //得到图片地址,基础地址拼接上传成功返回的key
                _this.detailimgobj.push(obj)
              } 
            })
          } else {
            this.$Message.warning('上传的图片不能大于 4M')
          }
          this.$refs.fileinputs.value = '' // 删除图片时,也删除input里面的file对象
        } else {
          this.$Message.warning('最多选择五张图片')
        }
      } else {
        this.flagshowimg = false
      }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Vue中上传图片到阿里OSS,你可以按照以下步骤进行操作: 1. 安装依赖:首先,你需要安装ali-oss这个阿里OSSJavaScript SDK。可以使用npm或者yarn进行安装: ```shell npm install ali-oss --save # 或者 yarn add ali-oss ``` 2. 创建OSS实例:在你的Vue组件中,引入ali-oss,并创建一个OSS实例。在创建实例时,你需要提供阿里OSS的相关配置,包括accessKeyId、accessKeySecret、region和bucket等信息。例如: ```javascript import OSS from 'ali-oss'; const client = new OSS({ accessKeyId: 'your_access_key_id', accessKeySecret: 'your_access_key_secret', region: 'your_region', bucket: 'your_bucket_name' }); ``` 请将上述代码中的`your_access_key_id`、`your_access_key_secret`、`your_region`和`your_bucket_name`替换为你自己的阿里OSS配置信息。 3. 处理文件上传:在Vue组件中,你可以使用input[type="file"]元素来接收用户选择的文件。然后,通过监听change事件,获取到用户选择的文件对象。接下来,你可以使用OSS实例的`put`方法将文件上传到阿里OSS。例如: ```javascript // 在模板中添加input[type="file"]元素 <input type="file" @change="handleFileUpload"> // 在Vue组件中定义处理文件上传的方法 methods: { async handleFileUpload(event) { const file = event.target.files[0]; try { // 生成唯一的文件名 const fileName = `${Date.now()}-${file.name}`; // 将文件上传到阿里OSS const result = await client.put(fileName, file); console.log('文件上传成功', result); // 在这里可以将上传成功后的文件URL保存到数据库或者展示在页面上等操作 } catch (error) { console.error('文件上传失败', error); } } } ``` 在上述代码中,`handleFileUpload`方法会在用户选择文件后被调用。它会获取到用户选择的文件对象,并使用OSS实例的`put`方法将文件上传到阿里OSS。上传成功后,你可以根据需要对文件URL进行后续处理。 希望以上步骤能够帮助到你。如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值