Appearance
亚马逊文件上传
将亚马逊文件上传 相关代码 归纳成一个 aws.js
插件文件,大家可直接使用此文件调用即可。
aws.js
对应代码如下
js
import crypto from "crypto-js"
import dayjs from "dayjs"
import x2js from 'x2js'
const uploadFileToAWS = async (filePath, callback) => {
let { data } = await apiGetAwsProperties()
let index = filePath.lastIndexOf('/')
let fileKey = filePath.substring(index+1)
await uploadToS3(filePath, fileKey, data.sessionToken, data.bucketName, data.region, data.accessKeyId, data.secretAccessKey, callback)
}
// http://bucket.s3.region.amazonaws.com -> http://sigv4examplebucket.s3.ap-northeast-1.amazonaws.com
const uploadToS3 = async (filePath, fileKey, token, bucket, region, accessKeyId, secretAccessKey, callback) => {
let x2jsInstance = new x2js()
let prefix = ""
let index = fileKey.lastIndexOf('.')
fileKey = fileKey.substring(index)
let name = dayjs.utc().format('YYYYMMDDHHmmss')+'_'+random_number(6)+fileKey
let key = prefix ? prefix+name : name
let url = `http://${bucket}.s3.${region}.amazonaws.com`
// 终端节点endpoint: s3.ap-northeast-1.amazonaws.com
let formData = getAWSFormData(prefix, key, token, bucket, region, accessKeyId, secretAccessKey)
let fileUrl = ''
await uni.uploadFile({
url,
filePath,
name: 'file',
formData,
timeout: 10000,
success: async (res) => {
// console.log('上传成功', res);
// 解析 XML 响应
let json = x2jsInstance.xml2js(res.data)
fileUrl = json?.PostResponse?.Location ?? ''
// console.log("json=", json)
// console.log("fileUrl=", fileUrl)
if (fileUrl) {
callback ? callback({fileUrl: fileUrl}) : ''
}
},
fail: (error) => {
// 在这里可以处理上传失败的情况
console.error('上传失败', error);
},
});
}
const getAWSFormData = (prefix, key, token, bucket, region, accessKeyId, secretAccessKey) => {
let fileType = "image/jpg,image/png"
let serviceName = "s3"
let expiration = "2099-12-30T12:00:00.000Z"
let date = dayjs.utc().format('YYYYMMDDTHHmmss') + 'Z'
let today = dayjs.utc().format('YYYYMMDD')
let credential = `${accessKeyId}/${today}/${region}/s3/aws4_request`
let policyBase64 = getPolicyBase64(prefix, today, date, '', bucket, token, region, accessKeyId, expiration)
let signature = generateS3PostSignature(today, policyBase64, region, serviceName, secretAccessKey)
let formData = {
"key": key,
"bucket": bucket,
"acl": "public-read",
"x-amz-server-side-encryption": "AES256",
"x-amz-credential": credential,
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-date": date,
"x-amz-meta-tag": "",
"x-amz-security-token": token,
"x-amz-content-sha256": "UNSIGNED-PAYLOAD",
"success_action_status": "201",
"policy": policyBase64,
"x-amz-signature": signature,
}
return formData
}
const getPolicyBase64 = (prefix, today, date, fileType='', bucket, token, region, accessKeyId, expiration) => {
// 拼接实际访问的密钥ID
let credential = `${accessKeyId}/${today}/${region}/s3/aws4_request`
let policyBase64 = ""
let policy = {
expiration: expiration,
conditions: [
{ "bucket": bucket }, // 替换为你的 S3 存储桶名称
['starts-with', '$key', prefix],
{ "acl": 'public-read' },
{"x-amz-server-side-encryption": "AES256"},
["starts-with", "$x-amz-meta-tag", ""],
{"x-amz-credential": credential},
{"x-amz-algorithm": "AWS4-HMAC-SHA256"},
{"x-amz-date": date },
{"x-amz-content-sha256": "UNSIGNED-PAYLOAD"},
{ "success_action_status": "201"},
{"x-amz-security-token": token}
],
}
console.log("policy=", policy)
// 将policy 转换成base64编码 ---- policy政策
policyBase64 = Buffer.from(JSON.stringify(policy)).toString('base64')
return policyBase64
}
const getSignatureKey = (today, secretAccessKey, regionName, serviceName) => {
let kDate = crypto.HmacSHA256(today, "AWS4" + secretAccessKey)
let kRegin = crypto.HmacSHA256(regionName, kDate)
let kService = crypto.HmacSHA256(serviceName, kRegin)
let kSigning = crypto.HmacSHA256("aws4_request", kService)
return kSigning
}
const generateS3PostSignature = (today, policyBase64, regionName, serviceName, secretAccessKey) => {
// 获取签名密钥
let signingKey = getSignatureKey(today, secretAccessKey, regionName, serviceName)
// 计算签名
let signature = crypto.HmacSHA256(policyBase64, signingKey).toString(crypto.enc.Hex)
return signature
}
// 此方法通过 接口 获取 亚马逊 相关配置
function apiGetAwsProperties (body = {
}, options = {
}) {
const url = 'user/config/getAwsConfig';
return http.post(url, { ...body, ...options }, { custom },)
}
export default uploadFileToAWS
调用操作
此示例,在 uniapp
里 调用 aws.js
import uploadFileToAWS from "./aws"
uni.chooseImage({
count: 1,
success: async (res) => {
let filePath = res.tempFilePaths[0]
filePath ? uploadFileToAWS(filePath, (d) => {
d ?
(
console.log("d.fileUrl=", d.fileUrl)
) : ''
}) : ''
}
})