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

大文件上传,对接阿里oss采用前端分片技术。完成对应需求!

最近做了一个大文件分片上传的功能,记录下

1. 首先是安装阿里云 oss 扩展

composer require aliyuncs/oss-sdk-php

去阿里云 oss 获取配置文件

AccessKey ID = ***
AccessKey Secret = ***
Bucket名称 = ***
Endpoint = ***

2. 前端上传,对文件进行分片

<form id="add-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action=""><div class="form-group"><label class="control-label col-xs-12 col-sm-2">{:__('选择本地文件')}:</label><div class="col-xs-12 col-sm-8"><input type="file" id="fileInput"><div><a href="#" onclick="startUpload()"><i class="fa fa-upload"></i>选择完点击上传(请等待上传完成)</a></div><div id="progress" style="margin-top:10px;"></div></div></div><div class="form-group layer-footer"><label class="control-label col-xs-12 col-sm-2"></label><div class="col-xs-12 col-sm-8"><button type="submit" class="btn btn-primary btn-embossed disabled">{:__('OK')}</button></div></div>
</form><script>let chunkSize = 5 * 1024 * 1024; // 分片大小5MBlet uploadId = '';let objectName = '';let parts = [];const CHUNK_SIZE = 5 * 1024 * 1024; // 分片阈值5MBasync function startUpload() {const file = document.getElementById('fileInput').files[0];if (!file) {layer.msg('请选择文件', {icon: 1});}// 根据文件大小选择上传方式if (file.size <= CHUNK_SIZE) {await directUpload(file);} else {await chunkedUpload(file);}}// 开始上传async function directUpload(file) {const formData = new FormData();formData.append('file', file);formData.append('file_name', file.name);// 显示进度条const progressBar = document.getElementById('progress');progressBar.innerHTML = '上传进度:0%';try {const res = await fetch('/api/directUpload', {method: 'POST',body: formData,});const data = await res.json();if (data.code === 1) {progressBar.innerHTML = '上传进度:100%';$("#c-name").val(data.name);$("#c-fullurl").val(data.fullurl);layer.msg('上传成功', {icon: 1});} else {throw new Error(data.msg);}} catch (error) {progressBar.innerHTML = '上传失败';console.error('直接上传失败:', error);}}async function chunkedUpload(file) {const totalChunks = Math.ceil(file.size / CHUNK_SIZE);let uploadedChunks = 0;// 初始化分片上传const initRes = await fetch('api/initUpload', {method: 'POST',body: JSON.stringify({filename: file.name}),headers: {'Content-Type': 'application/json'}});const initData = await initRes.json();if (initData.code !== 1) return alert('初始化失败');const {uploadId, objectName} = initData;const parts = [];// 上传所有分片for (let i = 0; i < totalChunks; i++) {const start = i * CHUNK_SIZE;const end = Math.min(start + CHUNK_SIZE, file.size);const chunk = file.slice(start, end);const formData = new FormData();formData.append('part', chunk);formData.append('uploadId', uploadId);formData.append('objectName', objectName);formData.append('partNumber', i + 1);const uploadRes = await fetch('api/uploadPart', {method: 'POST',body: formData});const partData = await uploadRes.json();if (partData.code === 1) {parts.push({PartNumber: partData.partNumber,ETag: partData.etag});uploadedChunks++;// 更新进度const progress = (uploadedChunks / totalChunks * 100).toFixed(2);document.getElementById('progress').innerHTML = `上传进度:${progress}%`;}}// 合并分片const completeRes = await fetch('api/completeUpload', {method: 'POST',body: JSON.stringify({uploadId,objectName,parts: JSON.stringify(parts)}),headers: {'Content-Type': 'application/json'}});const completeData = await completeRes.json();if (completeData.code === 1) {$("#c-name").val(completeData.name);$("#c-fullurl").val(completeData.fullurl);layer.msg('上传成功', {icon: 1});} else {layer.msg('上传失败' + completeData.msg, {icon: 2});}}
</script>

2. 后端控制器

<?phpnamespace app\****;use OSS\Core\OssException;
use OSS\OssClient;class Attachment
{// 初始化分片上传public function initUpload(){$object = 'uploads/' . date('Ymd') . '/' . $this->request->post('filename');try {$ossClient = new OssClient(config('alioss.accessKeyId'),config('alioss.accessKeySecret'),config('alioss.endpoint'));$uploadId = $ossClient->initiateMultipartUpload(config('alioss.bucket'), $object);return json(['code' => 1,'uploadId' => $uploadId,'objectName' => $object]);} catch (OssException $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}// 上传分片public function uploadPart(){$data = $this->request->post();try {$ossClient = new OssClient(config('alioss.accessKeyId'),config('alioss.accessKeySecret'),config('alioss.endpoint'));$options = [OssClient::OSS_FILE_UPLOAD => $_FILES['part']['tmp_name'],OssClient::OSS_PART_NUM => $data['partNumber'],OssClient::OSS_CHECK_MD5 => true];$etag = $ossClient->uploadPart(config('alioss.bucket'),$data['objectName'],$data['uploadId'],$options);return json(['code' => 1,'etag' => $etag,'partNumber' => $data['partNumber']]);} catch (OssException $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}// 完成上传public function completeUpload(){$data = $this->request->post();try {$ossClient = new OssClient(config('alioss.accessKeyId'),config('alioss.accessKeySecret'),config('alioss.endpoint'));$result = $ossClient->completeMultipartUpload(config('alioss.bucket'),$data['objectName'],$data['uploadId'],json_decode($data['parts'], true));return json(['code' => 1,'url' => $result['oss-request-url'],'name' => pathinfo($data['objectName'], PATHINFO_FILENAME),'fullurl' => strstr($result['oss-request-url'], '?', true),]);} catch (OssException $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}// 直接上传完整文件public function directUpload(){try {$ossClient = new OssClient(config('alioss.accessKeyId'),config('alioss.accessKeySecret'),config('alioss.endpoint'));$file = $_FILES['file'];$file_name = $this->request->request('file_name', '');$object = 'uploads/' . date('Ymd') . '/' . $file['name'];$result = $ossClient->uploadFile(config('alioss.bucket'),$object,$file['tmp_name']);return json(['code' => 1,'url' => $result['oss-request-url'],'name' => pathinfo($file_name, PATHINFO_FILENAME),'fullurl' => $result['oss-request-url'],]);} catch (OssException $e) {return json(['code' => 0, 'msg' => $e->getMessage()]);}}
}

相关文章:

大文件上传,对接阿里oss采用前端分片技术。完成对应需求!

最近做了一个大文件分片上传的功能&#xff0c;记录下 1. 首先是安装阿里云 oss 扩展 composer require aliyuncs/oss-sdk-php 去阿里云 oss 获取配置文件 AccessKey ID *** AccessKey Secret *** Bucket名称 *** Endpoint *** 2. 前端上传&#xff0c;对文件进行分片…...

【场景分析】基于概率距离快速削减法的风光场景生成与削减方法

目录 1 主要内容 场景消减步骤 2 部分代码 3 程序结果 1 主要内容 该程序参考文献《含风光水的虚拟电厂与配电公司协调调度模型》场景消减部分模型&#xff0c;程序对风电场景进行生成并采用概率距离方法进行消减&#xff0c;程序先随机生成200个风电出力场景&#xff0c;然…...

【Java Web】3.SpringBootWeb请求响应

&#x1f4d8;博客主页&#xff1a;程序员葵安 &#x1faf6;感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb; 文章目录 一、请求 1.1 postman 1.2 简单参数 1.3 实体参数 1.4 数组集合参数 1.5 日期参数 1.6 JSON参数 1.7 路径参数 二、响应 2…...

单片机中断系统工作原理及定时器中断应用

文件目录 main.c #include <REGX52.H> #include "TIMER0.H" #include "KEY.H" #include "DELAY.H"//void Timer0_Init() { // TMOD 0x01; // TL0 64536 % 256; // TH0 64536 / 256; // ET0 1; // EA 1; // TR0 1; //}unsigned char…...

LangGraph-agent-天气助手

用于创建agent和多代理工作流 循环&#xff08;有迭代次数&#xff09;、可控、持久 安装langgraph包 conda create --name agent python3.12 conda activate agent pip install -U langgraph pip install langchain-openai设置 windows&#xff08;>结尾&#xff09; s…...

深度学习——超参数调优

第一部分&#xff1a;什么是超参数&#xff1f;为什么要调优&#xff1f; 一、参数 vs 超参数&#xff08;Parameter vs Hyperparameter&#xff09; 类型定义举例是否通过训练自动学习&#xff1f;参数&#xff08;Parameter&#xff09;是模型在训练过程中通过反向传播自动…...

阿里云API RAG全流程实战:从模型调用到多模态应用的完整技术链路

一、引言 在企业级智能应用开发中&#xff0c;如何让大模型高效利用动态数据并生成准确回答&#xff0c;是构建智能问答系统的核心挑战。阿里云提供的API RAG&#xff08;检索增强生成&#xff09;流程&#xff0c;通过整合通义千问大模型、百炼智能体平台与知识库管理体系&am…...

创建型:建造者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 工作流程 2.3 实现案例 2.4 变体&#xff1a;链式建造者&#xff08;常见于多参数对象&#xff0c;无需指挥者&#xff09; 3、优缺点分析 4、适用场景 1、核心思想 目的&#xff1a;将复杂对象的构建过程与其表示分离…...

Jenkins集成Docker与K8S构建

Jenkins 是一个开源的持续集成和持续交付(CI/CD)工具,广泛用于自动化软件开发过程中的构建、测试和部署任务。它通过插件系统提供了高度的可扩展性,支持与多种开发工具和技术的集成。 Jenkins 的核心功能 Jenkins 的主要功能包括自动化构建、测试和部署。它能够监控版本控…...

redis缓存实战-19(使用 Pub/Sub 构建简单的聊天应用程序)

实践练习:使用 Pub/Sub 构建简单的聊天应用程序 Redis Pub/Sub 是一项强大的功能,可在应用程序的不同部分之间实现实时通信。这是一种消息传递范例,其中发送方(发布者)不直接向特定接收方(订阅者)发送消息,而是将消息发布到通道。订阅者对一个或多个通道表示兴趣,并且…...

UE4游戏查找本地角色数据的方法-SDK

UE4中&#xff0c;玩家的表示通常涉及以下几个类&#xff1a; APlayerController: 代表玩家的控制逻辑&#xff0c;处理输入等。 APawn: 代表玩家在世界中的实体&#xff08;比如一个角色、一辆车&#xff09;。APlayerController 控制一个 APawn。 ACharacter: APawn 的一个…...

游园安排--最长上升子序列+输出序列

1.最长上升子序列&#xff0c;用二分贪心算法优化的那个 2.分割提取游客名字&#xff0c;与蓝肽子序列类似 3.关键是我不知道怎么输出答案序列&#xff0c;这里学习了一种不按序实现的&#xff0c;思想是倒序能凑上就加入&#xff0c;反正从ma开始遍历&#xff0c;生成一定是…...

缓存一致性与AI内容生成的幂等控制

缓存一致性与AI内容生成的幂等控制 在AI架构中&#xff0c;缓存系统作为提升响应速度与减少模型调用压力的关键组件&#xff0c;必须同时解决两个核心问题&#xff1a; 缓存一致性问题&#xff1a;数据源变动后&#xff0c;如何确保缓存及时更新、不过期、不脏读&#xff1b;…...

Java 连接并操作 Redis 万字详解:从 Jedis 直连到 RedisTemplate 封装,5 种方式全解析

引言 在分布式系统和高并发场景中&#xff0c;Redis 作为高性能内存数据库的地位举足轻重。对于 Java 开发者而言&#xff0c;掌握 Redis 的连接与操作是进阶必备技能。然而&#xff0c;从基础的 Jedis 原生客户端到 Spring 封装的 RedisTemplate&#xff0c;不同连接方式的原…...

python web 开发-Flask-Login使用详解

Flask-Login使用详解&#xff1a;轻松实现Flask用户认证 1. Flask-Login简介 Flask-Login是Flask框架的一个扩展&#xff0c;专门用于处理用户认证相关的功能。它提供了用户会话管理、登录/注销视图、记住我功能等常见认证需求&#xff0c;让开发者能够快速实现安全的用户认证…...

快速排序算法的C++和C语言对比

快速排序算法简介&#xff1a; 快速排序(Quick Sort)是一种高效的排序算法&#xff0c;采用分治法策略。它的基本思想是&#xff1a; 1. 从数列中挑出一个元素作为"基准" 2. 重新排序数列&#xff0c;所有比基准值小的元素放在基准前面&#xff0c;所有比基准值大的…...

分布式事务知识点整理

目录 分布式事务问题&#xff1f;问题场景引入分布式事务的理论标准BASE理论附CAP理论 Two-phase Commit&#xff0c;2PC2PC系统组件两阶段执行过程2PC缺点 Three-Phase Commit&#xff0c;3PC三阶段执行过程 TTC(Try-Confirm-Cancel)seata项目以及原理how to define a Distrib…...

微信小程序数据接收

1.微信小程序蓝牙模块中的 wx.onBLECharacteristicValueChange 回调函数有时候一个数据包会分多个数据包回调&#xff0c;有时候多个数据包会合并成一个数据包回调&#xff0c;如果接收到数据包就处理业务&#xff0c;分拆的和合并的数据都会因为解析失败&#xff0c;导致业…...

鸿蒙UI开发——badge角标的使用

1、概 述 badge小红点角标是我们项目开发中常见的需求&#xff0c;信息标记组件&#xff0c;可以附加在单个组件上用于信息提醒的容器组件。效果如下&#xff1a; 2、Badge 接口定义如下&#xff1a; &#x1f449;&#x1f3fb; 根据数字创建标记组件&#xff1b; Badge(v…...

批量打印的趣事

前言 PC端网页打印大量数据的时候&#xff0c;比如批量打印100个标签&#xff0c;会出现打印样式混乱的问题 问题 数据可以设定100~自定义阈值 {data.map((_, idx) > {return <Tag qrCode啊程是个大帅逼 code{AB-${idx1}} title雷猴 key{idx} />})} 打印预览到第3…...

车载中央域控制器测试【BCM模块介绍-外灯3】

文章目录 1 摘要2 倒车灯2.1 倒车灯的作用与功能2.2 控制实现方案2.3 需求分析2.3.1系统需求2.3.2 功能安全需求&#xff08;ISO 26262 ASIL B&#xff09;*2.3.3 关联功能需求 3 角灯3.1 角灯&#xff08;Cornering Lamp&#xff09;核心作用与功能3.2 控制实现方案3.3 需求分…...

Linux系统基础——是什么、适用在哪里、如何选

一、Linux是什么 Linux最初是由林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;基于个人兴趣爱好开发的个人项目&#xff0c;他编写了最核心的内核&#xff1b;后面为了发展壮大Linux系统他将整个项目开源到GitHub上&#xff0c;可以让全世界的人都参与到项目的开发维护中…...

MySQL与Oracle六大方面之比较

MySQL与Oracle作为两大主流关系型数据库&#xff0c;在功能、性能、适用场景等方面存在显著差异。以下是综合多个来源的全面对比分析&#xff1a; 1. 事务与并发控制 - 事务提交方式&#xff1a; - **MySQL**&#xff1a;默认自动提交&#xff08;可通过参数修改&#xff09;&…...

二层和三层交换机的概念

前言 交换机&#xff0c;和它最相关的莫过于Mac地址和在osi的数据链路层。本章的重点还是有请我们的小动物们出场&#xff0c;来一段小故事。 在交换机森林里&#xff0c;二层交换机&#x1f406;是独来独往的猎豹&#xff0c;靠MAC地址闪电般传递消息。一天&#xff0c;管理员…...

计算机网络学习20250524

协议 格式—语法&#xff1a;数据结构或格式&#xff08;怎么做&#xff09;次序—时序&#xff1a;事件实现的顺序&#xff08;做的顺序&#xff09;行为动作—语义&#xff1a;发出什么控制信息&#xff0c;完成何种动作、做出何种应答 网络结构 网络边缘&#xff1a;主机…...

无损图片压缩 本地处理 批量处理提升效率 无需联网+无广告

各位爱图人士们&#xff01;今天咱来聊聊速图压缩器&#xff0c;这可是个专注无损图片压缩的本地处理小能手&#xff01;它核心功能超牛&#xff0c;能在减少图片体积时还保持画质杠杠清晰。下面咱就详细说说它的主要功能和使用特点。 首先是无损压缩技术。它用高效压缩算法&a…...

C++标准库中 std::string 类提供的 insert 成员函数的不同重载版本

下图是C标准库中 std::string 类提供的 insert 成员函数的不同重载版本&#xff0c;可点击C标准库获取 以下是std::string::insert各重载版本的功能及参数解释&#xff1a; 1. 插入完整字符串 string& insert(size_t pos, const string& str); 功能&#xff1a;在字…...

Qt window frame + windowTitle + windowIcon属性(3)

文章目录 window frame属性window frame的概念1. window frame的影响2. 图片演示3. 代码演示 API接口widget.cpp&#xff08;测试代码&#xff09; windowTitle属性API接口问题 注意点widget.cpp&#xff08;属性用法&#xff09; windowIcon属性API接口啥是窗口图标玩法1. 先…...

解决:VMware 虚拟机 Ubuntu 系统共享文件夹无法访问问题

以下是解决 VMware 虚拟机 Ubuntu 系统共享文件夹无法访问 问题的完整过程总结&#xff0c;按关键步骤和逻辑顺序梳理&#xff1a; 系统版本&#xff1a;Ubuntu 22.04.5 1. 确认 VMware Tools 已安装 验证方法&#xff1a;通过 ps -ef | grep vmtoolsd 检查是否存在 vmtools…...

Dify源码学习

文章目录 1 大模型基本原理1.1 model_context_tokens、max_tokens和prompt_tokens1.1.1 三者之间的关系1.1.2 总结对比 2 Dify源代码2.0 前后端代码跑起来【0】准备开发环境【1】下载代码【2】运行后端&#xff08;1&#xff09;Start the docker-compose stack&#xff08;2&a…...