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.pswp.cn/web/93003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93003.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vscode uv 發布一個python包:編輯、調試與相對路徑導包

背景 最近一直在使用uv做python包管理&#xff0c;用起來很方便。 尤其是在代碼上傳到github的時候&#xff0c;pyproject.toml 會顯示出當前項目依賴的python包。這樣在把代碼下載到本地之后&#xff0c;直接uv sync就可以很方便地恢復出python環境。 uv 除了有上述優點&…

Secure 第四天作業

實驗需求&#xff1a;需求一拓撲&#xff1a;按照以上拓撲所示&#xff0c;完成以下需求&#xff1a;參考以上拓撲&#xff0c;配置設備IP地址&#xff0c;使用UNL里Secure第四天拓撲即可。&#xff08;有興趣的同學課后也可按照PPT原拓撲做做實驗&#xff09;&#xff1b;配置…

利用開漏輸出模式模擬IIC

/************************************************************利用IO口模擬IIC時序&#xff0c;需要使用2個IO口(SDA和SCL)SCL時鐘線只能由主器件進行控制&#xff0c;所以SCL引腳必須為輸出模式SDA數據線&#xff0c;在主器件發送數據時&#xff0c;SDA引腳為輸出模式SDA數…

閘機控制系統從設計到實現全解析:第 5 篇:RabbitMQ 消息隊列與閘機通信設計

第 5 篇&#xff1a;RabbitMQ 消息隊列與閘機通信設計RabbitMQ 是一款開源的消息隊列中間件&#xff08;Message Queue&#xff0c;MQ&#xff09;&#xff0c;基于 Erlang 語言開發&#xff0c;遵循 AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高級消息隊…

Linux 常用命令大全:覆蓋日常 99% 操作需求

1、基本命令 pwd&#xff1a;顯示當前工作目錄的絕對路徑&#xff0c;例如在復雜目錄結構中快速確認位置&#xff0c;執行后會輸出類似/home/user/documents的結果。 cd&#xff1a;切換目錄&#xff0c;cd 目錄路徑可進入指定目錄&#xff0c;cd ~回到當前用戶的家目錄&…

普通電腦與云電腦的區別有哪些?全面科普

近年來&#xff0c;越來越多的人不再購置升級自己的電腦&#xff0c;轉而選擇云電腦&#xff0c;云端產品正在變得越來越普及易用。那么它究竟跟我們的普通本地設備有什么區別吶&#xff1f;或許很多人并不知悉&#xff0c;對此&#xff0c;本篇內容小編就為大家簡要科普一下普…

【Python】支持向量機SVM

示例代碼&#xff1a;import numpy as np import matplotlib.pyplot as plt from sklearn import svm from sklearn.datasets import make_blobs from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, classification_report# 設…

當AI學會“抄近路”:殘差網絡如何突破深度學習的極限

**——解讀《Deep Residual Learning for Image Recognition》**今天我想帶大家回到2015年&#xff0c;見證人工智能領域的一場“捷徑革命”——由何愷明等人提出的**深度殘差學習框架&#xff08;ResNet&#xff09;**。這篇論文解決了困擾AI界多年的“深度詛咒”&#xff0c;…

HCIP--BGP綜合實驗

目錄 BGP綜合實驗報告 一、實驗拓撲 二、實驗要求 三、實驗思路 &#xff08;一&#xff09;IP地址規劃 &#xff08;二&#xff09;整體思路 四、實驗步驟 &#xff08;一&#xff09; IP地址配置 &#xff08;二&#xff09; AS2內部配置OSPF協議 &#xff08;三&a…

Java 基礎編程案例:從輸入交互到邏輯處理

在Java編程學習中&#xff0c;輸入輸出、循環控制和邏輯判斷是核心基礎。本文整理了10個經典案例&#xff0c;涵蓋Scanner輸入處理、斐波那契數列、成績統計、登錄驗證等場景&#xff0c;幫助初學者掌握編程邏輯與實用技巧。 一、Scanner輸入交互&#xff1a;獲取用戶輸入并處理…

LeetCode 面試經典 150_數組/字符串_整數轉羅馬數字(18_12_C++_中等)(模擬)(對各位進行拆解)

LeetCode 面試經典 150_數組/字符串_整數轉羅馬數字&#xff08;18_12_C_中等&#xff09;題目描述&#xff1a;輸入輸出樣例&#xff1a;題解&#xff1a;解題思路&#xff1a;思路一&#xff08;模擬&#xff09;&#xff1a;思路二&#xff08;對各位進行拆解&#xff09;&a…

計算機網絡摘星題庫800題筆記 第6章 應用層

第6章 應用層 6.1 網絡應用的架構 考點 1 CS 架構 題組闖關 1.DNS 是基于 ( ) 模式的分布式系統。 A. C/S B. B/S C. P2P D. 以上均不正確 1.【參考答案】A 【解析】本題考查網絡應用模型。 DNS 作為分布式應用&#xff0c;是一種典型的 C/S 模式&#xff0c;是隨著 Internet 技…

BLUCK電路的輸入電容應該怎么選取

借用TI的BULK芯片討論一下輸入電容怎么選取的問題&#xff0c;BULK電源是我們常用的電源&#xff0c;它的原理請看之前的文章&#xff1a; 高壓差為何不用LDO&#xff1f;DCDC效率更高&#xff01;-CSDN博客 本文我們探討一下輸入電容&#xff0c;輸入電容是控制紋波的關鍵&a…

CAN仲裁機制的原理

我們來詳細講 CAN 仲裁機制 的原理和工作方式,這是 CAN 總線最核心的特性之一。 1?? 基本概念 CAN 總線是 多主機、多節點的串行總線,所有節點共享一根差分信號線(CAN_H / CAN_L)。 每個節點都可以隨時發送消息(多主機機制) 總線只能同時有一個節點成功發送 仲裁 用…

【GPT入門】第46課 vllm安裝、部署與使用

【GPT入門】第46課 vllm安裝、部署與使用 1.準備服務器 2. 安裝 conda環境,隔離base環境 3. vllm使用 3.1 在線推理, openai兼容服務器 3.2 模型離線調用 4. 沒有使用GPU問題分析 1.準備服務器 cuda 版本選12.1 vllm官網介紹: https://vllm.hyper.ai/docs/getting-started/…

【從網絡基礎到實戰】理解TCP/IP協議體系的核心要點(包含ARP協議等其他協議介紹)

前言&#xff1a; 學習計算機網絡不僅是軟件開發的基礎功&#xff0c;更是成為一名合格后端工程師、網絡工程師的重要門檻。本文將基于 TCP/IP 協議體系&#xff0c;系統梳理網絡層、數據鏈路層、以及相關協議的核心知識&#xff0c;并結合實際案例與代碼示例幫助理解。一、網絡…

Python 元類基礎:從理解到應用的深度解析

在 Python 的高級編程中&#xff0c;元類&#xff08;metaclass&#xff09; 無疑是最神秘又最強大的特性之一。它不僅是構建類的“工廠”&#xff0c;更是 Python 靈活對象模型的體現。本文將帶你從基礎概念入手&#xff0c;深入理解元類的本質、工作機制以及實際應用&#xf…

Nginx 配置代理服務器的詳細方法

一、什么是代理服務器&#xff1f; 類型說明正向代理客戶端通過代理訪問目標服務器&#xff08;隱藏客戶端身份&#xff09;反向代理客戶端訪問代理服務器&#xff0c;由代理服務器請求后端服務器&#xff08;隱藏后端服務器&#xff09; 二、Nginx 反向代理配置方法&#xff…

Lombok插件介紹及安裝(Eclipse)

一、Lombok 的用途 Lombok是一個 Java 庫&#xff0c;通過注解的方式簡化 Java 代碼的編寫。它能夠自動生成常見的代碼&#xff0c;如getter、setter、toString、equals、hashCode等方法&#xff0c;從而減少樣板代碼&#xff0c;使代碼更加簡潔、易讀。 Lombok 通過添加**Dat…

硬核操作!Go 語言生成 “會爬墻的清潔機器人”,玻璃外墻自己擦

本文聚焦于利用 Go 語言開發 “會爬墻的清潔機器人” 這一硬核技術&#xff0c;圍繞該機器人如何實現玻璃外墻自主清潔展開。首先介紹開發背景與需求&#xff0c;接著闡述 Go 語言在其中的優勢&#xff0c;詳細講解機器人的核心技術&#xff0c;包括吸附系統、運動控制、清潔機…