H5 微信小程序可用的前端直传阿里云OSS(STS临时凭证+前端签名)直接下载插件
下面是原理说明:
明白了,我来详细说明前端上传文件到阿里云OSS需要携带的具体参数:
- 从服务器获取的 STS 凭证:
javascript
// 这些参数需要从你的后端服务器获取
{
accessKeyId: "STS.xxxx", // STS临时访问密钥ID
accessKeySecret: "yyyy", // STS临时访问密钥Secret
securityToken: "zzzz", // STS安全令牌
expiration: "2024-10-24T12:00:00Z" // 过期时间
}
- 上传文件时实际发送给阿里云的表单数据:
javascript
formData: {
// 必须参数
'key': 'uploads/example.jpg', // 文件存储的路径+名称
'OSSAccessKeyId': 'STS.xxxx', // STS临时访问密钥ID
'policy': 'xxxxxx', // Base64编码的策略文本
'signature': 'yyyy', // 签名字符串
'x-oss-security-token': 'zzzz', // STS安全令牌
// 可选参数
'success_action_status': '200', // 上传成功后的返回码
'Content-Type': 'image/jpeg', // 文件类型
'x-oss-meta-uuid': 'uuid', // 自定义元信息前缀
}
实际调用示例:
javascript
constructor(config) {
// 设置 OSS 服务的 URL
this.url = config.url || 'https://yanyuguodu.oss-cn-beijing.aliyuncs.com/';
// 设置访问密钥 ID
this.accessKeyId = config.accessKeyId || '';
// 设置访问密钥 Secret
this.accessKeySecret = config.accessKeySecret || '';
// 设置安全令牌
this.securityToken = config.securityToken || '';
// 定义策略文本
const policyText = {
"expiration": config.expiration, // 策略过期时间
"conditions": [
["content-length-range", 0, 1048576000] // 文件大小限制
]
}
// 对策略文本进行 Base64 编码
this.policy = Base64.encode(JSON.stringify(policyText));
}
// 定义异步方法 ossUpload,用于上传文件
async ossUpload(filePath, name, dir) {
// 生成文件的完整路径
// const key = dir + this.random_string(10) + this.get_suffix(name);
const key = dir + name;
// 生成签名
const bytes = HMAC(SHA1, this.policy, this.accessKeySecret, { asBytes: true });
const signature = util.bytesToBase64(bytes);
// 返回一个 Promise 对象
return new Promise((resolve, reject) => {
// 使用 uni.uploadFile 方法上传文件
uni.uploadFile({
url: this.url, // 上传地址
filePath: filePath, // 文件路径
name: 'file', // 文件字段名
formData: {
name, // 文件名
key, // 文件路径
policy: this.policy, // 策略
// 作用:指定上传的条件和限制
// 包含:
// - 过期时间 expiration
// - 文件大小限制 content-length-range
// - 允许的文件类型
// - 其他限制条件
//下面是必填参数
OSSAccessKeyId: this.accessKeyId, // 访问密钥 ID
success_action_status: '200', // 成功状态码
signature, // 签名
'x-oss-security-token': this.securityToken // 安全令牌
},
// 上传成功的回调函数
success: () => {
resolve({ success: true, data: this.url + key });
},
// 上传失败的回调函数
fail: () => {
reject({ success: false, data: '上传失败' });
}
});
});
}