前端使用vue+element上傳文件到oss

      在以前的開發當中都是後臺處理上傳,前端負責上傳接口調用,一直也沒涉及和處理到直傳到阿里雲對象存儲服務(oss),本次主要也是參考自掘金大神的同篇文章,而後根據實際的修改,將我的開發中所遇到的問題和心得,一塊兒分享。html

使用oss

1.使用 NPM 安裝ali-oss前端

npm install ali-oss複製代碼

2.寫一個公用的ali-oss.js算法

// 引入ali-oss
let OSS = require('ali-oss')

/**
 *  [accessKeyId] {String}:經過阿里雲控制檯建立的AccessKey。
 *  [accessKeySecret] {String}:經過阿里雲控制檯建立的AccessSecret。
 *  [bucket] {String}:經過控制檯或PutBucket建立的bucket。
 *  [region] {String}:bucket所在的區域, 默認oss-cn-hangzhou。
 */
let client = new OSS({
  region: '<oss region>',
  secure: true,  // secure: 配合region使用,若是指定了secure爲true,則使用HTTPS訪問  
  accessKeyId: '<Your accessKeyId>',
  accessKeySecret: '<Your accessKeySecret>',
  bucket: '<Your bucket name>'
})複製代碼

官網方法示例點這裏
npm

3.調用apiapi

/** 
*  上傳文件,大小不能超過5GB 
* @param {string} ObjName OSS的儲存路徑和文件名字 
* @param {string} fileUrl 本地文件 
* @retruns Promise 
*/
export const put = async (ObjName, fileUrl) => {  
  try {    
    let result = await client.put(`${ObjName}`, fileUrl)    
    // ObjName爲文件名字,能夠只寫名字,就直接儲存在 bucket 的根路徑,如需放在文件夾下面直接在文件名前面加上文件夾名稱    
    return result  
  } catch (e) {    
   console.log(e)  
  }
}
// 上傳成功以後,轉換真實的地址
export const signatureUrl = async (ObjName) => {  try {    let result = await client.signatureUrl(`${ObjName}`)    // fileName爲文件夾, ObjName爲文件名字,能夠只寫名字,就直接儲存在 bucket 的根路徑    return result  } catch (e) {    console.log(e)  }}

// 後臺只須要傳入文件名,回顯時候一樣也只是返回文件名,說作數據遷移管理時候不麻煩,反正意思就是上傳出現問題都和他們無關,so,沒辦法,因此須要本身根據返回文件名進行轉碼,生成所須要的url複製代碼
export const signatureUrl = async (ObjName) => {  
  try {    
    let result = await client.signatureUrl(`${ObjName}`)    
    return result  
  } catch (e) {    
    console.log(e)  
  }
}
複製代碼

4.保證上傳文件的惟一性,網上找的算法(能夠根據具體需求來),隨機生成文件名跨域

/** 
* 生成隨機文件名稱 
* 規則八位隨機字符,加下劃線鏈接時間戳 
*/
export const getFileNameUUID = () => {  
  function rx() {    
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)  
  }  
  return `${+new Date()}_${rx()}${rx()}`
}複製代碼

使用element的 upload 組件進行上傳

Element-UI的 Upload 組件有一個 http-request 配置,能夠自定義上傳方法,覆蓋默認的。bash

直接貼代碼dom

<template>
  <div class="hello">
    <el-upload
      class="upload-demo"
      action
      :http-request="handleUpload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :before-remove="beforeRemove"
      :before-upload="beforeUpload"
      multiple      
      :limit="limit"
      :on-exceed="handleExceed"
      :file-list="fileList"
      :list-type="listType"
    >
      <el-button size="small" type="primary">點擊上傳</el-button>
      <div slot="tip" class="el-upload__tip">{{ tip }}</div>
    </el-upload>
  </div>
</template>

<script>
import { put, signatureUrl, getFileNameUUID } from '@/utils/ali-oss'

export default {
  name: 'Upload',
  props: {
    tip: {
      type: String,
      default: '上傳大小不能超過80M'
    },
    limit: {
      type: Number,
      default: 1
    },
    action: {
      type: String,
      default: ''
    },
    headers: {
      type: Object,
      default: () => {}
    },
    name: {
      type: String,
      default: ''
    },
    listType: {
      type: String,
      default: 'text'
    }
  },
  data() {
    return {
      fileList: []
    }
  },
  methods: {
    handleRemove(file, fileList) {
      this.$emit('on-remove', file, fileList)
    },
    handlePreview(file) {
      this.$emit('on-preview', file)
    },
    handleExceed(files, fileList) {
      this.$message.warning(`每次只能上傳 ${this.limit} 個文件`)
    },
    beforeRemove(file, fileList) {
      return this.$confirm(`肯定移除 ${file.name}?`)
    },
    handleSuccess(response, file, fileList) {
      this.fileList = fileList
      this.$emit('on-success', file, fileList)
    },
    beforeUpload(file) {      
      // 限制上傳類型      
      const fileExtensions = getFileName(file.name) === '.doc' || getFileName(file.name) === '.docx' || getFileName(file.name) ==='.pdf'      
      //限制的上限爲20M      
      const max20M = file.size / 1024 / 1024 < 20;      
      if (!fileExtensions) {        
        this.$message.error('上傳文件類型只能是 .doc, .docx, .pdf 格式!');      
      }      
      if (!max20M) {        
        this.$message.error('上傳文件大小不能超過 20MB!');      
      }      
      return fileExtensions && max20M;    
    },
    /**
     * 自定義上傳方法
     */
    handleUpload(option) {
      // 獲取文件的後綴名
      let objName = getFileNameUUID()
      var obj = option.file.name
      var index = obj.lastIndexOf(".");      
      obj = obj.substring(index,obj.length);
      // 生成的文件名,保留文件後綴名,進行拼接      
      let objName = getFileNameUUID() + getFileName(option.file.name)

      // 調用 ali-oss 中的方法,flieName是存放的文件夾名稱,可本身定義
      put(`flieName/${objName}`, option.file).then(res => {        
        console.log(res)
        // 上傳成功以後,轉換真實的地址
        signatureUrl(`flieName/${objName}`).then(res => {          console.log(res)        })
      })
    }
  }
}
</script>
複製代碼

最後,提交到後臺保存文件地址

上傳到阿里雲OSS成功後,會返回文件的地址,提交給後臺保存地址就能夠了。
async


若是遇到跨域問題,請參考官網的配置

oss跨域配置post


主要來源自: juejin.im/post/5d1c05…
相關文章
相關標籤/搜索