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替換成你設置的樣式名。

結語

本人也是剛接觸這個,實現的也是最基本的功能,實現過程也可能並不正確。有作過這個的童鞋們能夠多給點意見,謝謝。🙏

相關文章
相關標籤/搜索