vue中图片上传到阿里云oss记录

最近项目需求,做一个图片上传到阿里云oss的功能,由于之前没做过这样的功能,所以也是查阅了不少资料,边写demo边测试把基本功能完成了。现在来记录下,没做过的童鞋也可以简单参考下。我的使用场景是在vue项目中结合iview框架的上传组件来实现功能。

首先给大家一篇阿里云的文档 web端直传实践,它里面给出了三个上传的例子,如下图:

最开始我们后端让我自己看看这些例子,也没决定好用哪种方式,而我选择尝试的是第一种方式,因为不需要后端直接参与。那我就先从第一种方式开始说起,在这之前你需要开通好阿里云的对象存储功能,并新建了一个 Bucket,这些我就直接略过了,给个文档: 使用阿里云OSS

JavaScript客户端签名直传

这种方式不需要后端直接参与,你只需要配置好阿里云oss的后台就好,非常方便。但是客户端通过JavaScript把AccesssKeyID和AccessKeySecret写在代码里面有泄露的风险。关于AccesssKeyID和AccessKeySecret,参考上面给的文档里的介绍。

每种方式官方都给出了demo代码,你可以下载下来参考一下,不过我觉得例子代码有点多,就没用他那种方式。阿里云提供了一个sdk可以帮助我们来实现文件上传。这里是SDK参考

我是直接使用它的cdn引入的,在index.html中直接引入:

<script src="https://gosspublic.alicdn.com/aliyun-oss-sdk.min.js"></script>
复制代码

之前说了我是结合iview框架的上传组件的,我把上传功能单独写成了一个组件,为防止大家看的难受,这里只贴上部分核心代码:

template:

// iview上传组件
<Upload
    :before-upload="handleBeforUpload"   // before-upload 上传文件之前的钩子,参数为上传的文件
    action=""
>
    <Button icon="ios-cloud-upload-outline">选择文件</Button>
</Upload>

// 显示选择的图片名
 <div v-if="file">已选择文件:{{file.name}}
 
 // 手动点击上传
<Button @click="upLoad">点击上传</Button>

复制代码

script:

data(){
    return {
        file:'' // 选择上传的文件
    }
},

methods:{
    // 上传之前的操作
    handleBeforUpload (file) {
      this.file = file  // 将回调的文件信息存入data.file
      return false     // 返回false,表示手动上传,取消默认的自动上传
    },
    
    // 点击上传按钮触发上传操作
    upload(){
        // sdk提供的创建客户端实例方法
        const client = new OSS.Wrapper({
            region: 'oss-cn-hangzhou',   // 创建Bucket时会选择不同地区,根据自己的选择填入对应名称
            accessKeyId: '********',     // 填入你的accessKeyId
            accessKeySecret: '********', // 填入你的accessKeySecret
            bucket: '***'                // 填入你的bucket名
        })
        
        const Name = this.file.name
        const suffix = Name.substr(Name.indexOf('.'))              // 文件后缀
        const filename = Date.parse(new Date()) + suffix           // 组成新文件名
        
        client.multipartUpload(filename, this.file).then(res => {   // 上传
            console.log('上传成功:',res)
            // ... 你的操作,可以拼接图片url,用于显示等...
        }).catch(err => {
            console.log('上传失败:', err)
        })
    }
}
复制代码

以上就是一个最简单的上传图片功能,总结就是:取消iview组件默认的自动上传功能,选择手动上传,在上传之前拿到图片信息,在点击上传按钮时,借助sdk提供的方法,填入你的OSS参数,最后将图片上传。上传成功之后,可以到OSS管理控制台的文件管理中看到图片信息。

服务端签名直传并设置上传回调

我和后端最终选择的方式就是这种,至于为啥,显然上面那种方法看起来不那么安全,更多的区别还是去看文档介绍的。 同样的,这种方法也提供了demo,但是我依旧没用它的方式去实现我的功能。我还是先贴上少部分核心的代码,其中上面的template部分不用变,主要来看看js部分的实现:

首先handleBeforUpload中,我们需要加一步获取参数的方法,并组成要上传的数据

handleBeforUpload (file) {
  this.file = file
  // 获取上传文件前服务器给的参数
  this.$store.dispatch('handleGetAllOss').then(res => {
    this.setParams(res.data)  // 组装我们要上传的数据,方法的代码在下面
  })
  return false
},
复制代码

我使用了vuex,所以请求都写在了actions里,handleGetAllOss这个action里会请求一些上传需要的参数,请求地址是需要后端提供的,所以如果用这种方式的话,后端大佬的大腿要抱牢。关于请求我就不多说了,就简单发个ajax的get请求拿到参数就好。想要知道会有哪些参数,我们重点来看setParams这个方法:

setParams (data) {
  // data 是我上一步骤传过来的参数object
  
  // 这个url是要上传时的地址,存在data的host上
  this.url = data.host

  const Name = this.file.name
  const suffix = Name.substr(Name.indexOf('.'))      // 文件后缀
  const filename = Date.parse(new Date()) + suffix   // 组成新的文件名
    
  // 新建formData对象,使用append方法添加字段,在data中拿的都是请求回来的参数
  let formData = new FormData()
  formData.append('key', data.dir + storeAs)
  formData.append('policy', data.policy)
  formData.append('OSSAccessKeyId', data.accessid)
  formData.append('success_action_status', '200')
  formData.append('callback', data.callback)
  formData.append('signature', data.signature)
  
  formData.append('name', Name)       // 文件名
  formData.append('file', this.file)  // 文件,选择时存在data上
  
  this.formData = formData    // 将formData对象存入data中,方便后续使用
},

复制代码

现在我们有了要上传的数据this.formData,有了上传地址:this.url,现在只要使用ajax的post请求就好了,当点击上传按钮时,调用upload方法:

upload(){
    this.$store.dispatch('handleUploadImg', { url: this.url, data: this.formData }).then(res => {
        console.log('上传成功:',res)
        // 你的操作
    }).catch(err => {
        console.log('上传失败:',err)
    })
}

复制代码

我还是把我的啰嗦的代码贴出来吧

handleUploadImg方法:

// 上传
handleUploadImg ({ commit }, { url, data }) {
  return new Promise((resolve, reject) => {
    uploadImg({ url, data })     // 方法在下面
      .then(res => {
        resolve(res)
      })
      .catch(err => {
        reject(err)
      })
  })
}
复制代码

uploadImg方法:

const uploadImg = ({ url, data }) => {
  return axios.request({    // axios.request 方法是简单的对axios的封装,看这配置也应该不需要多介绍
    url,
    data,
    method: 'post',
    headers: { 'Content-Type': 'multipart/form-data' }
  })
}
复制代码

上面的流程就是这种上传方式的简单实现,你不必按照我的方式来,总结一下就是:

  1. 请求后端给你的地址,拿到上传时必要的参数
  2. 将获取的参数拼装至formData
  3. 使用post方法发送请求,带上formData数据,请求地址在步骤1的参数里,host参数。
  4. post请求成功后的回调,是后端可控的,我让后端加了一个图片名返回,自己拼接图片url。

这个过程需要后端的参与。

图片处理(缩略图)

本来没这步的,想想还是写上来,觉得阿里云这个功能挺好用的。

通过上面的两种方式可以成功上传图片到阿里云的对象存储,然后就可以使用url访问图片了。一般上传成功后,在页面上会显示一个缩略图,这个缩略图不仅仅是你设置宽高看起来小,实际上它真的可以变小。在阿里云OSS管理控制台,点击图片处理,点击新建样式,你会看到下面这样:

如图你可以在右侧添加一个图片样式,比如可以选择缩略比例,设置好后点确定就会生成一个图片样式,我图中已经有一个min_img名的样式,表示缩略图的意思,这样在我想要访问某个图片的缩略图时,在图片url后面加上?x-oss-process=style/min_img这个后缀就好了,min_img替换成你设置的样式名。

结语

本人也是刚接触这个,实现的也是最基本的功能,实现过程也可能并不正确。有做过这个的童鞋们可以多给点意见,谢谢。?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值