当前位置: 首页 > news >正文

oss(阿里云)前端直传

  • WEB端前端直传

参考文档:web前端直传并设置上传回调

封装oss-upload.ts

// 图片上传
import { uploadToken } from '@/api/uploadFile.js' // 获取oss token接口// 定义 OSS 信息类型
interface OssInfo {policy: string;signature: string;x_oss_credential: string;x_oss_date: string;dir: string;security_token: string;callback: string;host: string;data?: {filename?: string;url?: string;};
}// 定义 uploadToken 返回数据类型
interface UploadTokenResponse {status_code: number;data: OssInfo;
}let ossInfo: OssInfo | null = null// 定义文件类型
type FileWithMetadata = File & {base64?: string;width?: number;height?: number;url?: string;fileType?: string;raw?: File;thumbdata?: string;
};/*** 文件上传数组* 过滤已上传文件* @param {FileWithMetadata[]} files 要上传的文件数组* @returns {Promise<{ sucArr: FileWithMetadata[]; failArr: FileWithMetadata[] }>} 包含上传成功和失败文件的Promise*/
export async function fileUpload(files: FileWithMetadata[]): Promise<{ sucArr: FileWithMetadata[]; failArr: FileWithMetadata[] }> {const sucArr: FileWithMetadata[] = []const failArr: FileWithMetadata[] = []return new Promise((resolve) => {const result = files.reduce((accumulatorPromise: Promise<void>, next: FileWithMetadata) => {return accumulatorPromise.then(() => { // 上一个接口执行完毕再执行下一个if (!next.url || !next.url.includes(import.meta.env.VITE_APP_UPLOAD_API)) {return uploadItemHandle((next.fileType === 'file' && next.raw) ? next.raw : next).then((res) => {sucArr.push(res)}).catch((res) => {failArr.push(res)})} else {sucArr.push(next)}})}, Promise.resolve())result.then(() => {console.log('All Promises Resolved', { sucArr, failArr })resolve({ sucArr, failArr })})})
}/*** 文件处理* @param {FileWithMetadata} file 要上传的文件* @returns {Promise<FileWithMetadata>} 包含上传成功文件的Promise*/
function uploadItemHandle(file: FileWithMetadata): Promise<FileWithMetadata> {return new Promise(async(resolve, reject) => {if (!ossInfo) { // 减少调用接口次数const data = await uploadToken() as UploadTokenResponseif (Number(data.status_code) === 200) {ossInfo = data.data}}if (!ossInfo) return reject(file)const formData = new FormData()formData.append('success_action_status', '200')formData.append('policy', ossInfo.policy)formData.append('x-oss-signature', ossInfo.signature)formData.append('x-oss-signature-version', 'OSS4-HMAC-SHA256')formData.append('x-oss-credential', ossInfo.x_oss_credential)formData.append('x-oss-date', ossInfo.x_oss_date)formData.append('key', ossInfo.dir + file.name) // 文件名formData.append('x-oss-security-token', ossInfo.security_token)formData.append('callback', ossInfo.callback) // 添加回调参数formData.append('file', file) // file 必须为最后一个表单域try {const response = await fetch(ossInfo.host, { method: 'POST', body: formData })if (!response.ok) throw new Error(`请求失败: ${response.status}`)const imgData = await response.json()if (imgData.status === 200 && imgData.data) {file.thumbdata = imgData.data.filename || ''file.url = imgData.data.url || ''resolve(file)} else {console.error(JSON.stringify(imgData))reject(file)}} catch (error) {console.error(error)reject(file)}})
}

调用:

await fileUpload(list).then(arr => {if (arr.failArr.length === 0) {console.log('上传数据返回:',arr)} else {ElMessage({ message: `有文件上传失败请重新上传!`, type: 'error', duration: 2 * 1000 })}
}).catch(() => {return { sucArr: [] }
})

微信小程序端
参考文档:微信小程序端前端直传
ossUpload.js

(function () {const {request} = require('./request')let ossInfo = nullfunction uploadFile(filePath, success, fail, options, progress, cancelTask) {let successResult = []let failResult = []const result = filePath.reduce((accumulatorPromise, next) => {return accumulatorPromise.then(() => { // 上一个接口执行完毕再执行下一个return uploadItem(next).then((res => {successResult = successResult.concat(res)})).catch(res => {failResult = failResult.concat(res)})})}, Promise.resolve())result.then(e => {if (failResult.length === 0) success(successResult)else fail(successResult)})}// 正式上传的前置方法,做预处理function uploadItem(file) {return new Promise(async (resolve, reject) => {if (!ossInfo) {const data = await getOssToken()if (Number(data.status_code) === 200) {ossInfo = data.dataossInfo = data}}console.log('file',file)if (!ossInfo) return reject(file)// 上传参数const formData = {key:file.tempFilePath.split('/').pop(), //上传文件名称policy: ossInfo.policy, //表单域'x-oss-signature-version': ossInfo.xOssSignatureVersion, //指定签名的版本和算法'x-oss-credential': ossInfo.xOssCredential, //指明派生密钥的参数集'x-oss-date': ossInfo.xOssDate, //请求的时间'x-oss-signature': ossInfo.xOssSignature, //签名认证描述信息'x-oss-security-token': ossInfo.xOssSecurityToken, //安全令牌success_action_status: ossInfo.success_action_status //上传成功后响应状态码};// 发送请求上传文件 wx.uploadFile({// Bucket域名 请替换为目标Bucket域名url: ossInfo.base_url, // 此域名仅作示例,实际Bucket域名,请替换为您的目标Bucket域名。filePath: file.tempFilePath,name: 'file', //固定值为fileformData: formData,success(res) {console.log('上传响应:', res);if (res.statusCode === 200) {resolve(res.data); // 上传成功} else {console.error('上传失败响应:', res);reject(res); // 上传失败,返回响应}},fail(err) {console.error('上传失败:', err); // 输出错误信息reject(err); // 调用回调处理错误}});})}// 获取阿里云tokenfunction getOssToken() {return new Promise((resolve, reject) => {const data = {url: 'api/sts-token', // 获取oss token接口method: 'post'}request(data, true, false, '操作中...', 2000).then((res) => {resolve(res)}).catch((err) => {reject('token获取失败' + err)})})}module.exports = {uploadFile}
})();

使用:
index.js

const {uploadFile} = require('../../utils/ossUpload')Component({data: {image: [],},pageLifetimes: {show() {if (typeof this.getTabBar === 'function') {this.getTabBar((tabBar) => {tabBar.setData({selected: 0})})}}},methods: {onUpload() {uploadFile(this.data.image, (res) => {console.log('成功', res)this.onSubmit()}, (err) => {console.log('失败', err)})},onSubmit() {console.log('好啦')},uploadImg() {wx.chooseMedia({count: 9,mediaType: ['image', 'video'],sourceType: ['album', 'camera'],maxDuration: 30,camera: 'back',success: (res) => {console.log(res.tempFiles)this.setData({image: res.tempFiles})}})}}
})

index.wxml:

<button bind:tap="uploadImg">上传</button>
<image wx:for="{{image}}" src="{{item.tempFilePath}}" mode="" />
<button bind:tap="onUpload">提交</button>
http://www.lryc.cn/news/619896.html

相关文章:

  • 4G模块 ML307A通过MQTT协议连接到阿里云
  • ImportError: Encountered error: Failed to import NATTEN‘s CPP backend.
  • 事件处理与组件基础
  • 飞算JavaAI实现数据库交互:JPA/Hibernate + MyBatis Plus基础功能学习
  • 基于微信小程序的工作日报管理系统/基于asp.net的工作日报管理系统
  • CAD 的 C# 开发中,对多段线(封闭多边形)内部的点进行 “一笔连线且不交叉、不出界
  • 重生之我在公司写前端 | “博灵语音通知终端” | 登录页面
  • [量化交易](1获取加密货币的交易数据)
  • 01数据结构-Prim算法
  • Unity、C#常用的时间处理类
  • Gradle(三)创建一个 SpringBoot 项目
  • C++ 中构造函数参数对父对象的影响:父子控件管理机制解析
  • 【完整源码+数据集+部署教程】火柴实例分割系统源码和数据集:改进yolo11-rmt
  • 学习语言的一个阶段性总结
  • Linux操作系统应用编程——文件IO
  • Nginx的SSL通配符证书自动续期
  • 精准阻断内网渗透:联软科技终端接入方案如何“锁死”横向移动?
  • MySQL中的查询、索引与事务
  • MySQL三大存储引擎对比:InnoDB vs MyISAM vs MEMORY
  • RuoYi-Cloud 接入 Sentinel 的 3 种限流方式
  • Android 双屏异显技术全解析:从原理到实战的多屏交互方案
  • Ubuntu 20.04 虚拟机安装完整教程:从 VMware 到 VMware Tools
  • 基于.Net Framework4.5 Web API 引用Swagger
  • nginx高性能web服务器实验
  • INTERSPEECH 2025 | 数据堂诚邀您参加MLC-SLM挑战赛暨研讨会
  • JVM安全点轮询汇编函数解析
  • 【个人简单记录】PLT,GOT函数加载机制
  • 海康视觉平台VM创建项目
  • FxSound:为你的音频体验注入专业级享受
  • Android图片加载库Glide深度解析与实践指南