阿里云的oss真的文档写辣鸡, 直传的demo代码也辣鸡, 代码一坨一坨的。
如果你被oss困住了, 那么你看这篇就完全可以解决问。
一句话可以概括的非要写一堆, 加密请求
前端直传的话有现成的例子
https://help.aliyun.com/document_detail/31925.html
但是这个里面代码特别不适合移植, 直接写重点就好了(吐槽: 里面一堆满足自己场景的代码)。
然后推荐后台签名, 返回签名前端就不需要暴露账户了, 子账号都不需要, 安全程度高, 并且不麻烦。
现在官方有go, java, php, python等语言, 咩有nodejs, 那就自己写, 很简单。
主要是生成这两个字段。
policy
signature
用js(nodejs), 不需要任何安装第三方包。
前端拿到后就可以发起请求了。
代码如下:
const crypto = require('crypto')
const config = {
secret: 'xxxx',
OSSAccessKeyId: 'xxxx',
host: 'http://xxx.xxx.vip',
}
exports.OssSing =
// (params) => new Promise((resolve, reject) => {
ApiHook((v, resolve, reject) => {
const dirPath = '/'
const {OSSAccessKeyId, host, secret} = config
let end = new Date().getTime() + 300000
let expiration = new Date(end).toISOString()
let policyString = {
expiration,
conditions: [
["content-length-range", 0, 1048576000],
// ["starts-with", "$key", dirPath]
]
}
policyString = JSON.stringify(policyString)
const policy = new Buffer(policyString).toString('base64')
const signature = crypto.createHmac('sha1', secret).update(policy).digest('base64')
let res = {
OSSAccessKeyId: OSSAccessKeyId,
host,
policy,
signature,
saveName: end,
startsWith: dirPath
}
resolve(res)
})
上面starts-with被我注释了, 打开的话需要产生交互,就是前端把key传过来,然后后台再传回去。
前端的话, 更简单了, 拿到签名直接直传oss, 不需要消耗服务器啦。
以axios为请求库做例子, 代码参考:
import axios from 'axios'
export default async function(file, cb, errorcb){
let params = {
token: Store.getState().Common.userInfo.token
}
let ossInfo = await Http.shop['ossSign'](params)()
{
// 如果有企业和店铺的时候这里要做区分,分便统计
let key = `commodity/${ossInfo.saveName}`
/* eslint-disable no-undef */
let param = new FormData() // 创建form对象
param.append('name', file.name) // 通过append向form对象添加数据
param.append('key', key)
param.append('policy', ossInfo.policy)
param.append('OSSAccessKeyId', ossInfo.OSSAccessKeyId)
param.append('success_action_status', 200)
param.append('signature', ossInfo.signature)
param.append('file', file, file.name) // 通过append向form对象添加数据
// console.log(param.get('file')) // FormData私有类对象,访问不到,可以通过get判断值是否传进去
let config = {
headers: {'Content-Type': 'multipart/form-data'}
}
// 添加请求头
axios.post(ossInfo.host, param, config)
.then(response => {
// console.log('上传成功')
// console.log(response)
let url = `${ossInfo.host}/${key}`
// console.log(url)
cb(url)
})
}
}
--ok--
效果如下
预览啥的, 完全自己控制。 sdk里面,还不好改, (前两年用过, 那封装的改的很麻烦)
【如果有需要楼上上传组件的, 我可以考虑开源, 有预览, 加载中, 上传中, 删除, 个数限制】
--其他--
如果出现上传成功但是图片无法访问,基本都是阿里云管理系统配置问题。(比如仓库的类型不能是归档)
--END--