vue项目中上传文件到阿里云oss方法

这篇具有很好参考价值的文章主要介绍了vue项目中上传文件到阿里云oss方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上传背景介绍

在项目需求中,关于图片、视频、文件等上传文件,一般不是直接放置在自己的后台服务器上,一般都会购买云服务进行存储。譬如阿里云的oss对象存储。

那么,前端开发项目中,涉及到上传的功能时,我们不是把文件上传到自己的后台服务器,而是阿里云上面去,然后拿到文件的访问地址,例如图片的地址,再传递给后台保存下来,保存的是一个阿里云存储地址。

那么,前端如何实现阿里云oss文件上传功能呢?

vue项目中上传文件到阿里云oss方法官方文档上说了:(阿里云oss文档地址)
1、使用阿里云上传的SDK来上传到阿里云oss
2、不使用sdk的方式,直接使用post表单提交到阿里云oss去
3、小程序(忽略)

其实,也就两种。要么使用阿里云给的sdk,他封装的上传方法等;要么使用表单提交,像提交到我们自己服务器一样。

上传方式1:表单直传

Web端通过表单上传方式直接上传数据到OSS。

官方说有如下三种实现方式。

1、在客户端通过JavaScript代码完成签名,然后通过表单直传数据到OSS。详情请参见JavaScript客户端签名直传。
2、在服务端完成签名,然后通过表单直传数据到OSS。详情请参见服务端签名后直传。
3、在服务端完成签名,并且服务端设置了上传后回调,然后通过表单直传数据到OSS。OSS回调完成后,再将应用服务器响应结果返回给客户端。详情请参见服务端签名直传并设置上传回调。

我司采用的是第2中,服务端签名后,前端在直传oss。

可以理解为:上传前,需要通过阿里云给的账号生成钥匙,然后前端拿到钥匙后去开阿里云oss的门,不然,阿里云怎么你有没有给他交钱呢?服务端签名,就是把这个生成钥匙的过程放到了自己后台服务上,让他们去把钥匙给我们。我们前端自己不保管这么敏感的资料。

具体可以看这里https://help.aliyun.com/document_detail/31926.htm?spm=a2c4g.11186623.0.0.3627344eM9Gwj8#concept-en4-sjy-5db

封装的上传示例代码如下:

// fileUpload.js
import { v4 as uuidv4 } from 'uuid'
import axios from 'axios'
let basePath  = 'www.yourapi.com' // 你的服务器接口域名
/**
 * @description: 文件附件上传
 * file: 文件raw对象
 * successCallback: 成功的回调函数
 * errCallBack: 错误的回调函数
 * progressCallback: 上传进度的回调函数
 * dir: 上传阿里云目标文件夹 eg:图片image,视频video等
 */
const upload = function(file, successCallback = new Function(), errCallBack = new Function(), progressCallback = new Function(), dir = 'image') {
  let fileName = file.name
  axios({
    method: 'get',
    url: basePath + '/aliyun/get', // 请求签名接口,找后台要
    params: {
      dir: dir // 'image'   // 这里的参数,对应的就是上传到那个文件夹下面,找后台要
    }
  })
    .then(res => {
    // 拿到签名信息后,组装表单数据,作参考,具体的字段找后台要
      let obj = res.data.data
      let config = {}
      config.host = obj['host']
      config.policyBase64 = obj['policy']
      config.accessid = obj['accessId']
      config.signature = obj['signature']
      config.expire = parseInt(obj['expire'])
      config.callbackbody = obj['callback']
      config.dir = obj['dir']
      let fd = new FormData(),
        uuid = uuidv4(),
        key = config.dir + uuid
      fd.append('key', key)
      fd.append('success_action_status', '200')
      fd.append('x-oss-object-acl', 'public-read')
      fd.append('x-oss-meta-fullname', fileName)
      fd.append('OSSAccessKeyId', config.accessid)
      fd.append('policy', config.policyBase64)
      fd.append('signature', config.signature)
      fd.append('success_action_status', '200')
      fd.append('file', file)
      if (config.host.indexOf('http:') > -1) {
        var protocol = window.location.protocol || 'http:'
        var subUrl = config.host.substring(5, config.host.length)
        config.host = protocol + subUrl
      }
      // 数据组装完成后,发送上传请求到阿里云oss
      axios({
        url: config.host,
        method: 'POST',
        data: fd,
        processData: false,
        cache: false,
        contentType: false,
        // 这里,我们可以做上传经度
        onUploadProgress: function(progressEvent) {
          if (progressEvent.lengthComputable) {
            let percent = (progressEvent.loaded / progressEvent.total) * 100 || 0
            progressCallback({
              percent: percent
            })
          }
        }
      })
        .then(() => {
        // 拿到结果后,做其他操作
          let size = file.size > 1000000 ? parseFloat(file.size / 1000000).toFixed(2) + 'M' : parseFloat(file.size / 1000).toFixed(2) + 'KB'
          successCallback({
            attachment: fileName,
            aliyunAddress: key,
            size: size,
            host: config.host
          })
        })
        .catch(err => {
          errCallBack(err)
        })
    })
    .catch(err => {
      errCallBack(err)
    })
}
export default upload

那么,在element-ui upload组件中使用自定义上传功能:

<template>
<div class="text-msg-pic-upload">
    <el-upload
      :class="{ display: uploadDisabled }"
      list-type="picture-card"
      ref="upload"
      action
      multiple
      :http-request="handleUpload"
      :auto-upload="autoUpload"
      :limit="limit"
      :file-list="tempFileList"
      :on-exceed="handleExceed"
      :on-success="handleSuccess"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :before-upload="beforeUpload"
      :on-preview="handlePictureCardPreview"
      accept="jpg,.jpeg,.png,.JPG,.JPEG"
    >
      <i class="el-icon-plus"></i>
      <div slot="tip" class="el-upload__tip" v-if="tipsFlag">{{ tips }}</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" append-to-body>
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
    <div class="Upload_pictures">
      <ul class="el-upload__tip cBBBDBF" style="color: #BBBDBF;">
        <li>支持PNGJEPG格式 ,不超过2MB。</li>
      </ul>
    </div>
  </div>
</template>

<script>
import upload from '@/utils/fileUpload.js'
export default {
  name: 'UploadImageDemo',
  props: {
    width: {
      type: String,
      default: '240px'
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    limit: {
      type: Number,
      default: 3
    },
    limitType: {
      type: Array,
      default: () => ['image/jpeg', 'image/png', 'image/jpg']
    },
    disabled: {
      type: Boolean,
      default: false
    },
    imgList: {
      type: Array,
      default: () => []
    },
    tipsFlag: {
      type: Boolean,
      default: false
    },
    tips: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 上传文件列表,el-upload使用,临时保存数据。
      tempFileList: this.imgList,
      host: '', // 阿里云上传服务器地址根路径
      uploadDisabled: false,
      dialogImageUrl: '',
      dialogVisible: false
    }
  },
  watch: {
    // 解决第二渲染接口, 图片还保留着原来的问题 JerryYi
    imgList: {
      immediate: true,
      handler(val) {
        this.tempFileList = val
      }
    }
  },
  computed: {
    upText() {
      return this.autoUpload ? '上传文件' : '选择文件'
    }
  },
  created() {
  },
  mounted() {},
  methods: {
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    beforeUpload(file) {
      // console.log('beforeUpload', file)
      let types = this.limitType
      const isImage = types.includes(file.type)
      const isLt20M = file.size / 1024 / 1024 < 10

      if (!isImage) {
        this.$message({
          message: types.length == 0 ? '上传图片只能是 PNG 格式!' : '上传图片只能是 JPG、PNG 格式!',
          type: 'warning'
        })
        return false
      }
      if (!isLt20M) {
        this.$message.error('上传图片大小不能超过 1MB!')
        return false
      }
      return isImage && isLt20M
    },
    // 自定义上传操作
    handleUpload(op) {
      let dir = `images`
       upload(
        op.file,
         res => {
          let temp = {
            name: res.attachment,
            url: res.host + '/' + res.aliyunAddress
           }
          this.host = res.host
          op.onSuccess(temp)
         },
        err => {
          console.log(err)
         },
        res => {
          op.onProgress(res)
         },
         dir
       )
    },
    // 上传成功后触发
    handleSuccess(response, file, fileList) {
      this.filterFileFn(fileList)
    },
    // 返回给接口要用的格式
    filterFileFn(fileList) {
      let filterArr = fileList
        .filter(item => !item.status || item.status !== 'ready') // 过滤未上传的文件
        .map(item => {
          let url = item.response ? item.response.url : item.url
          return {
            url: url, // item.url || item.response.url
            name: item.name
          }
        })
      // console.log('fileList', fileList)
      this.$emit('onSuccessFiles', filterArr)
    },
    // 监听移除文件列表
    handleRemove(file, fileList) {
      if (file.status === 'success') {
        this.filterFileFn(fileList)
      }
    },
    handleExceed(files, fileList) {
      this.$message({ message: `当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`, type: 'warning' })
    },
    beforeRemove() {
      // return this.$confirm(`确定移除 ${file.name}?`)
    }
  }
}
</script>

<style>
.text-msg-pic-upload .el-upload--picture-card,
.text-msg-pic-upload .el-upload-list--picture-card .el-upload-list__item {
  width: 62px;
  height: 62px;
  line-height: 72px;
}
.display .el-upload--picture-card {
  display: none;
}
</style>

使用:

<UploadImage :limit="9" :imgList="fileImgList" @onSuccessFiles="onSuccessImgFiles" />

// ...........其他略
data(){
return{
	fileImgList: [{ name: 'test', url: 'http://testworldunion.oss-cn-shanghai.aliyuncs.com/scrm/1000/test/450821d6-13e1-464e-bc32-569fd277be2c.jpg' }] //图片列表
	}
},
methods: {
	// 监听图片上传
    onSuccessImgFiles(files) {
      console.log('onSuccessImgFiles', files)
      this.fileImgList = files
    }
}



一句话: 使用el-upload的自定义上传,结合我们封装的函数,实现上传功能。

上传方式二:阿里云oss SDK上传

具体可以看这里:https://help.aliyun.com/document_detail/64047.htm?spm=a2c4g.11186623.0.0.119f3967Xq1Eb8#concept-64047-zh

这种方式,需要安装依赖包或引入js文件。

npm install ali-oss   

同样的,我们封装一下上传:

import { v4 as uuidv4 } from 'uuid'
import axios from 'axios'

let basePath  = 'www.yourapi.com' // 你的服务器接口域名

const OSS = require('ali-oss')

/**
 * 阿里云oss sdk文件上传
 * @param {*} file 文件流
 * @param {*} successCallback 成功回调
 * @param {*} errCallBack 失败回调
 * @param {*} bucketName 阿里云桶名(可以指定多个桶名)
 * @param {*} dir 上传文件夹路径  譬如images
 */

export function bucketUpload(file, successCallback = new Function(), errCallBack = new Function(), bucketName = '你的阿里云桶名', dir = 'image') {
  let fileName = file.name
  let pathName = window.location.host
  let bucketNameTemp = bucketName
  let requestData = {
    bucket: bucketNameTemp,
    dir: dir
  }
  // 先获取上传要的资料签名
  axios({
    method: 'post',
    url: basePath + '/aliyunsts', // 找后台要接口,返回new OSS需要的参数
    headers: {
      'Content-Type': 'application/json'
    },
    data: requestData  // 这里的参数,看后台要什么,沟通确定
  })
    .then(res => {
      let obj = res.data || {}
      let config = {}
      // console.log(obj)
      config.host = obj.OssUrl
      // 实例化一个上传客户端
      const client = new OSS({
        // yourRegion填写Bucket所在地域。Region填写为oss-cn-hangzhou。
        region: obj.OssRegion,
        // 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
        accessKeyId: obj.AccessKeyId,
        accessKeySecret: obj.AccessKeySecret,
        // 从STS服务获取的安全令牌(SecurityToken)。
        stsToken: obj.SecurityToken,
        // 填写Bucket名称。
        bucket: obj.BucketName
      })

      try {
        // 填写Object完整路径。Object完整路径中不能包含Bucket名称。
        // 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
        // data对象可以自定义为file对象、Blob数据或者OSS Buffer。

        // 为保证唯一性,通过uuid将文件名替换
        let uuid = uuidv4() + fileName.substring(fileName.lastIndexOf('.'))
        if (dir.substring(dir.length - 1, 1) !== '/') {
          dir += '/'
        }
        const result = client.put(dir + uuid, file)
        result
          .then(res => {
            console.log(res)
            let size = file.size > 1000000 ? parseFloat(file.size / 1000000).toFixed(2) + 'M' : parseFloat(file.size / 1000).toFixed(2) + 'KB'
            successCallback({
              attachment: fileName,
              aliyunAddress: res.url,
              size: size,
              host: config.host
            })
          })
          .catch(err => {
            errCallBack(err)
          })
      } catch (e) {
        console.log(e)
      }
    })
    .catch(err => {
      errCallBack(err)
    })
}

对应的el-upload中的自定义上传方法就改了:

  handleUpload(op) {
      let bucketName = 'myaliyunossbucketname' // 桶名
      let dir = `images`
      bucketUpload(
        op.file,
        res => {
          let temp = {
            name: res.attachment,
            url: res.aliyunAddress
          }
          this.host = res.host
          op.onSuccess(temp)
        },
        err => {
          console.log(err)
        },
        bucketName,
        dir
      )

这种方式,有点缺陷,就是不能使用上传进度。

如果要使用上传进度,就需要使用分片上传功能才行。

vue项目中上传文件到阿里云oss方法
我们简单上传使用的这个put方法。不支持进度功能。

进度功能,需要使用另外一个方法:
vue项目中上传文件到阿里云oss方法
所有的api方法可以参考:
https://www.npmjs.com/package/ali-oss

当然,也可以参考阿里云oss上传的官方文档:
https://help.aliyun.com/document_detail/383952.html文章来源地址https://www.toymoban.com/news/detail-455447.html

到了这里,关于vue项目中上传文件到阿里云oss方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 文件上传对接阿里云OSS

    1.首先注册登陆阿里云,在产品里找到oss服务  2.点击开通oss服务后,可以看到oss服务面板  3.创建一个Bucket文件存储桶 Bucket 相当于 dir =bbs/avatar 用作文件隔离 4.java对接oss服务 找到java SDK 5.导入SDK的依赖  如果使用的是Java 9及以上的版本,则需要添加jaxb相关依赖。添加jaxb相关

    2024年02月05日
    浏览(40)
  • 阿里云对象存储OSS文件上传

    阿里云oss地址: 对象存储OSS_云存储服务_企业数据管理_存储-阿里云 阿里云对象存储OSS是一款海量、安全、低成本、高可靠的云存储服务,提供12个9的数据持久性,99.995%的数据可用性和多种存储类型,适用于数据湖存储,数据迁移,企业数据管理,数据处理等多种场景,可对

    2024年02月12日
    浏览(32)
  • Vue3 - 超详细 “纯前端“ 将文件上传到阿里云 OSS 对象存储,最新阿里云 SDK 上传音频、视频、图片、文档、office 等(保姆级详细示例源码教程,每行代码都有注释小白一看就懂)

    网上的教程大部分都过时了,各种不规范的写法五花八门(各种文件引入关系贼难改),对于新手来说真的无从下手。 本文站在新手的角度, 在 vue3 项目开发中,超详细 “纯前端(无需后端)” 上传各种图片图像、文档、音视频文件、压缩包到阿里云oss存储,利用 SDK 前端

    2024年02月03日
    浏览(30)
  • Golang操作阿里云OSS上传文件

    为什么要使用OSS?应用场景是什么? 最近在开发考试系统,里面需要上传课件,课件包括pdf,map等等各种类型的文件,这些文件不能像图片一样,直接上传到项目目录下面,需要单独存放,阿里云就提供了存储方式,然后OSS是其中的一种,可以用来存储一些文件。 我们需要

    2024年02月02日
    浏览(35)
  • SpringCloud整合阿里云OSS实现文件上传

    阿里云OSS官网:OSS管理控制台 (aliyun.com) 什么是对象存储OSS 阿里云对象存储OSS(Object Storage Service)是一款海量、安全、低成本、高可靠的云存储服务,可提供99.9999999999%(12个9)的数据持久性,99.995%的数据可用性。多种存储类型供选择,全面优化存储成本。 OSS具有与平台无

    2023年04月13日
    浏览(30)
  • springboot整合阿里云oss实现文件上传

    通过阿里云oss进行文件上传,首先需要开通相关的服务,这边就不在具体说明,不懂的可以百度看一下。 阿里云oss有几个关键的参数,这也是后续通过java进行上传所需要的参数,分别是endpoint(域结点)、AccessKey ID(秘钥id)、AccessKey secret(秘钥)、bucket name(bucket域名)。  通过这几

    2024年01月25日
    浏览(38)
  • SpringBoot整合阿里云Oss实现文件图片上传

    目录 1. 阿里云Oss注册使用 2. 项目中使用 2.1 引入依赖以及插件 2.2 编写配置文件application.properties 2.3 创建常量类,获取配置信息  2.4 serviceImpl中实现逻辑            

    2024年02月08日
    浏览(42)
  • 微信小程序文件直接上传阿里云OSS

    第一步 配置Bucket跨域访问 第二步 微信小程序配置域名白名单 以上两步,请参考阿里云官网, 如何在微信小程序环境下将文件上传到OSS_对象存储 OSS-阿里云 https://help.aliyun.com/document_detail/92883.html 安装依赖 wx-oss-upload 然后创建自己的上传方法,引用 wx-oss-upload  然后在选取文

    2024年02月11日
    浏览(42)
  • 【案例实战】SpringBoot整合阿里云文件上传OSS

    1.需求背景 C端业务用户头像上传 海量图片音频、视频存储 用户行为日志存储 (1)阿里云OSS介绍 对象存储OSS(Object Storage Service)是阿里云提供的海量、安全、低成本、高持久的云存储服务。其数据设计持久性不低于99.9999999999%(12个9),服务设计可用性不低于99.995%。 OSS具

    2024年02月06日
    浏览(35)
  • node.js - 上传文件至阿里云oss

    deploy.js

    2024年02月08日
    浏览(31)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包