前端文件上传金山云

以前公司上传文件都是后端给个请求地址,前端按照后端需要的格式发送请求,后端返回给前端一个服务器可以访问的文件地址,前端再连同其他表单数据进行提交。新公司前端是自己上传金山云直接拿到服务器可以访问的地址(当然上传金山云的签名需要后端返回),再跟其他表单数据请求提交。下面说一下流程

框架:@vue-cli4.5.11

UI库: ant-design-vue1.7.5

相关文档参考:对象存储(KS3)POST Object-金山云

一. 获取签名接口

src/api/common.js

import request from '@/utils/request'

export default class CommonServer {
  // 获取金山云上传签名
  static getKsOssSign (params) {
    return request({
      url: '/ks3/policy/signature',
      method: 'get',
      params
    })
  }
}

二. 自定义文件上传到金山云的名称

src/utils/oss.js

import moment from 'moment' //npm或yarn安装moment

// 文件扩展名提取
export const fileType = fileName => {
  return fileName.substring(fileName.lastIndexOf('.') + 1)
}

/**
 * oss路径定义
 * @param file
 * @param customFileType 自定义的扩展名
 */
export const ossPath = (file, customFileType) => {
  const folder = moment().format('YYYY-MM-DD')
  const name = moment().format('YYYY-MM-DD-HH-mm-ss-SSS')
  if (file.name) {
    const type = fileType(file.name)
    return `项目名称(金山云上创建的对应项目文件名)/upload/${folder}/${type}/${name}.${type}`
  } else if (customFileType) {
    return `项目名称(金山云上创建的对应项目文件名)/upload/${folder}/${customFileType}/${name}.${customFileType}`
  }
}

三. 金山云上传

src/utils/oss.js

import CommonServer from '@/api/common'

/**
 * 金山云上传
 * @returns {Promise<any>}
 */
export const ksOssUpload = (file, customFileType) => {
  return new Promise((resolve, reject) => {
    const key = ossPath(file, customFileType)
    const params = { fileName: key }
    CommonServer.getKsOssSign(params).then(res => {
      const { accessid, policy, signature, host } = res
      const formData = new FormData()
      formData.append('acl', 'public-read')
      formData.append('key', key)
      formData.append('signature', signature)
      formData.append('KSSAccessKeyId', accessid)
      formData.append('policy', policy)
      formData.append('file', file)
      axios.post(`https://${host}`, formData).then(res => {
        const { status } = res
        if (status === 200) {
          const data = {
            url: `https://${host}/${key}`,
            type: file.name ? fileType(file.name) : customFileType
          }
          resolve(data)
        } else {
          reject(res)
        }
      }).catch(err => {
        reject(err)
      })
    }).catch(err => {})
  })
}

四. 其他上传限制判断

src/utils/oss.js

import { message } from 'ant-design-vue'

/**
 * 上传文件大小限制
 * @param file
 * @param fileMaxSize
 * @returns {boolean}
 */
export const isMaxFileSize = (file, fileMaxSize = 1) => {
  if (!file) return false
  const isMaxSize = file.size / 1024 / 1024 < fileMaxSize
  if (!isMaxSize) {
    message.error(`上传文件大小不能超过${fileMaxSize}MB!`)
    return false
  }
  return true
}

/**
 * 文件最大数量限制
 * @param fileList
 * @param maxLength
 * @returns {boolean}
 */
export const isMaxFileLength = (fileList = [], maxLength = 3) => {
  if (fileList.length >= maxLength) {
    message.error(`最多上传${maxLength}个文件`)
    return false
  }
  return true
}

/**
 * 判断上传是否为图片
 * @param file
 * @returns {boolean}
 */
export const isImageFile = file => {
  if (!file) return false
  const types = [
    'image/png',
    'image/gif',
    'image/jpeg',
    'image/jpg',
    'image/bmp',
    'image/x-icon'
  ]
  const isImage = types.includes(file.type)
  if (!isImage) {
    message.error('上传文件非图片格式!')
    return false
  }
  return true
}

/**
 * 判断图片是否损坏
 * @param file
 */
export const isNormalImage = file => {
  return new Promise((resolve, reject) => {
    if (!file) return
    const image = new Image()
    image.src = file
    image.onload = () => {
      resolve({ status: 1, message: '加载成功' })
    }
    image.onerror = () => {
      // eslint-disable-next-line prefer-promise-reject-errors
      reject({ status: 0, errMsg: '图片损坏,请重新上传' })
    }
  })
}

五. 文件中使用

***.vue, 下面以ant-design-vue上传组件为例,这里只展示上传逻辑

<template>
  ...
  <a-upload v-bind="uploadProps">
      <a-button
        type="primary"
        :loading="loading"
        icon="upload"
      >
        点击上传
      </a-button>
  </a-upload>
  ...
</template>

<script>
  import { isMaxFileLength, isMaxFileSize, ksOssUpload } from '@/utils/oss'
  ...
  data () {
    return {
      uploadProps: {
        accept: '*',
        showUploadList: false,
        customRequest: async (param) => {
          if (!param.file) return
          if (!isMaxFileLength(this.mediaList, this.maxLength)) return
          if (!isMaxFileSize(param.file, 10)) return
          await this.handleUpload(param.file)
        }
      },
      maxLength:3,
      mediaList: [],
      loading: false
    }
  },
  methods{
    ...
    // 上传
    async handleUpload (file) {
      try {
        this.loading = true
        this.$message.loading('文件上传中')
        const { url } = await ksOssUpload(file)  //这里的就是上面src/utils/oss.js里面的上传
        this.mediaList.push(url)
        this.loading = false
        this.$message.success('文件上传成功!')
      } catch (e) {
        this.loading = false
        this.$message.destroy()
        this.$message.error(e || '文件上传失败')
      }
    }
  }
  
</script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值