在之前的开发当中都是后台处理上传,前端负责上传接口调用,涉及到直传到阿里云对象存储服务(oss),查阅了相关资料,分享出来希望能帮助到遇到这个需求的小伙伴,下面是具体的步骤。
使用oss
1.使用 npm安装ali-oss
npm install ali-oss --save
2.写一个公用的ali-oss.js
// 引入ali-osslet 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>'})
官网方法示例点这里
3.调用
/** * 上传文件,大小不能超过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) }}// 上传成功之后,转换真实的地址// 后台只需要传入文件名,回显时候同样也只是返回文件名,说做数据迁移管理时候不麻烦,反正意思就是上传出现问题都和他们无关,so,没办法,所以需要自己根据返回文件名进行转码,生成所需要的urlexport 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
配置,可以自定义上传方法,覆盖默认的。
<template><div class="hello"><el-uploadclass="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 = fileListthis.$emit('on-success', file, fileList)},beforeUpload(file) {// 限制上传类型const fileExtensions = getFileName(file.name) === '.doc' || getFileName(file.name) === '.docx' || getFileName(file.name) ==='.pdf'//限制的上限为20Mconst 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.namevar 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成功后,会返回文件的地址,提交给后台保存地址就可以了。
如果遇到跨域问题,请参考官网的配置
oss跨域配置