oss 直传对象存储

'use strict'
import Utils from './utils'
import { getSign, analysisCover } from '@/api/oss'
import { Message } from 'element-ui'
import axios from 'axios'
export default {
/**
* 创建随机字符串
* @param num
* @returns {string}
*/
randomString(num) {
const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
let res = ''
for (let i = 0; i < num; i++) {
var id = Math.ceil(Math.random() * 35)
res += chars[id]
}
return res
},
/**
* 创建oss客户端对象
* @returns {*}
*/
createOssClient(sign) {
return new Promise((resolve, reject) => {
// eslint-disable-next-line no-undef
const client = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: '*',
accessKeySecret: '*',
bucket: '*'
})
resolve(client)
})
},
/**
* 文件上传
* @param option 参考csdn: https://blog.csdn.net/qq_27626333/article/details/81463139
*/
ossUploadFile: function({ option, type }) {
const file = option.file
const extensionName = file.name.substr(file.name.lastIndexOf('.')) // 文件扩展名
var query = { module: type }
getSign(query).then(response => {
if (response.ok === true) {
const sign = response.data
const dateTime = Utils.dateFormat(new Date(), 'yyyyMMddhhmmss') // 当前时间
const randomStr = this.randomString(4)// 4位随机字符串
const fileName = sign.dir + '/' + dateTime + '_' + randomStr + extensionName // 文件名字(相对于根目录的路径 + 文件名)
const name = file.name // 获取图片的名称
const param = new FormData()
param.append('key', fileName) // 存储到oss的图片名称 自己定,必须确保唯一性,不然会覆盖oss中原有的文件
param.append('policy', sign.policy) // 服务器提供 policy
param.append('OSSAccessKeyId', sign.accessid) // 服务器提供 access_id
param.append('success_action_status', 200)
param.append('callback', sign.callback) // oss服务端的回调,服务器提供
param.append('callback_var', sign.callbackVar) // oss服务端的回调,服务器提供
param.append('signature', sign.signature) // 这个就是签名,最关键的,服务器提供
param.append('file', file, name) // 这个切记一定要放到最后去 append ,不然阿里云会一直报 key 的错误
const CancelToken = axios.CancelToken
const source = CancelToken.source()
axios({
url: sign.host,
method: 'post',
onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
if (progressEvent.lengthComputable) {
progressEvent.cancelSource = source
// 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
// 如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
option.onProgress(progressEvent)
}
},
data: param,
cancelToken: source.token
}).then(res => {
res.url = sign.host + '/' + fileName
option.onSuccess(res)
}).catch(error => {
if (error) {
option.onError(error)
}
})
} else {
option.onError(response)
}
})
},
// 转化 base64 为 blob
dataURItoBlob: (dataURI) => {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0] // mime类型
var byteString = atob(dataURI.split(',')[1]) // base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length) // 创建缓冲数组
var intArray = new Uint8Array(arrayBuffer) // 创建视图
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i)
}
return new Blob([intArray], { type: mimeString })
},
ossSimpleUpload({ type, file, okCallback, errCallback }) {
if (file.name != null) {
var that = this
const extensionName = file.name.substr(file.name.lastIndexOf('.')) // 文件扩展名
var query = { module: type }
getSign(query).then(response => {
if (response.ok === true) {
const sign = response.data
const dateTime = Utils.dateFormat(new Date(), 'yyyyMMddhhmmss') // 当前时间
const randomStr = that.randomString(4)// 4位随机字符串
const fileName = sign.dir + '/' + dateTime + '_' + randomStr + extensionName // 文件名字(相对于根目录的路径 + 文件名)
const name = file.name // 获取图片的名称
const param = new FormData()
param.append('key', fileName) // 存储到oss的图片名称 自己定,必须确保唯一性,不然会覆盖oss中原有的文件
param.append('policy', sign.policy) // 服务器提供 policy
param.append('OSSAccessKeyId', sign.accessid) // 服务器提供 access_id
param.append('success_action_status', 200)
param.append('callback', sign.callback) // oss服务端的回调,服务器提供
param.append('callback_var', sign.callbackVar) // oss服务端的回调,服务器提供
param.append('signature', sign.signature) // 这个就是签名,最关键的,服务器提供
param.append('file', file, name) // 这个切记一定要放到最后去 append ,不然阿里云会一直报 key 的错误
const CancelToken = axios.CancelToken
const source = CancelToken.source()
axios({
url: sign.host,
method: 'post',
onUploadProgress: function(progressEvent) { // 原生获取上传进度的事件
if (progressEvent.lengthComputable) {
// 将取消上传事件返回
progressEvent.cancelSource = source
// 属性lengthComputable主要表明总共需要完成的工作量和已经完成的工作是否可以被测量
// 如果lengthComputable为false,就获取不到progressEvent.total和progressEvent.loaded
file.onProgress(progressEvent)
}
},
data: param,
cancelToken: source.token
}).then(res => {
res.url = sign.host + '/' + fileName
if (okCallback) okCallback(res)
}).catch(error => {
if (error) {
if (errCallback) {
console.log(error)
if (error.message.code !== 30002) {
Message({
type: 'error',
message: 'oss 服务发生异常,请反馈给管理员!'
})
}
errCallback()
} else {
console.warn(`上传文件到阿里云 OSS 发生错误:${error}`)
}
}
})
} else {
if (errCallback) errCallback()
}
})
} else {
return false
}
},
analysisCoverAli: function(filePath) {
analysisCover(filePath)
}
}