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

最近项目需求,作一个图片上传到阿里云oss的功能,因为以前没作过这样的功能,因此也是查阅了很多资料,边写demo边测试把基本功能完成了。如今来记录下,没作过的童鞋也能够简单参考下。个人使用场景是在vue项目中结合iview框架的上传组件来实现功能。html

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

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

JavaScript客户端签名直传

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

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

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

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

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

template:axios

// 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部分的实现:bash

首先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替换成你设置的样式名。

结语

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

相关文章
相关标签/搜索