django vue3实现大文件分段续传(断点续传)

前端环境准备及目录结构:

 npm create vue 并取名为big-file-upload-fontend
通过 npm i  安装以下内容"dependencies": {"axios": "^1.7.9","element-plus": "^2.9.1","js-sha256": "^0.11.0","vue": "^3.5.13"},

在这里插入图片描述

main.js中的内容

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// app.use(ElementPlus)
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

App.vue 中的内容:

<template><div class="button"><el-uploadref="uploadRef"class="upload-demo":http-request="uploadFile":show-file-list="false"><el-button type="primary">点击上传文件</el-button></el-upload></div>
</template>
<script setup>
import axios from 'axios'
import {sha256} from 'js-sha256'const uploadFile = ({file}) => {// 每4MB为一个小文件const chunkSize = 4 * 1024 * 1024; // 4MB// 文件总大小const fileSize = file.size;// 分成了多少个片段const chunks = Math.ceil(fileSize / chunkSize);// 保证文件唯一const sha256Promise = sha256(file.name); // sha256的参数只接收字符串// 询问已经上传了几个片段const checkUploadedChunks = () => {return axios.post('http://127.0.0.1:8000/api/check', {sha256Promise: sha256Promise}).then(response => {return response.data; // response.data 就是下边的 uploadedChunks});};return checkUploadedChunks().then(async uploadedChunks => {if (uploadedChunks.length === chunks) {console.log("已经上传完成就不需要再重复上传")return Promise.resolve();}for (let i = 0; i < chunks; i++) {const formData = new FormData();// 将之前上传过的片段过滤掉,即不上传之前上传过的内容if (uploadedChunks.includes(i + 1)) {continue;}const start = i * chunkSize;// 将文件分片const chunk = file.slice(start, start + chunkSize);// 使用FormData形式上传文件formData.append('chunk', chunk);formData.append('chunkNumber', i + 1);formData.append('chunksTotal', chunks);formData.append('sha256Promise', sha256Promise);formData.append('filename', file.name);// 一次只上传一个片段,本次上传完成后才上传下一个const res = await axios.post('http://127.0.0.1:8000/api/upload', formData)}});
};
</script><style >
html, body{height: 100%;width: 100%;background-color: pink;
}
</style>

django后端环境及目录:

django-admin startproject big_file_upload_backend # 创建一个big_file_upload_backend项目
python版本:
Python 3.11.11
pip 需要安装:
Django                        5.0.6 
django-cors-headers           4.6.0  # 用于解决跨域 

在这里插入图片描述

big_file_upload_backend/settings.py 中的配置如下:

MIDDLEWARE = [......'django.contrib.sessions.middleware.SessionMiddleware',"corsheaders.middleware.CorsMiddleware",  # CorsMiddleware一定要在CommonMiddleware之前'django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware', #  注释掉这个'django.contrib.auth.middleware.AuthenticationMiddleware',......
]
# 并在文件最后添加上允许所有跨域
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = ('*')
# 将STATIC_URL = 'statics/' 替换为下边这三行
STATIC_URL = 'statics/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "../statics"),
]# 完整的setting设置如下:
"""
Django settings for big_file_upload_backend project.Generated by 'django-admin startproject' using Django 4.2.For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import os
from pathlib import Path# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-%sa^&p^%m3+m0ex%@y%la0(zzt4y4k3l%0=p#tipx-kz6w*#=d'# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = TrueALLOWED_HOSTS = []# Application definitionINSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles',
]MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware',"corsheaders.middleware.CorsMiddleware",'django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware','django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]ROOT_URLCONF = 'big_file_upload_backend.urls'TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [],'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]WSGI_APPLICATION = 'big_file_upload_backend.wsgi.application'# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databasesDATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': BASE_DIR / 'db.sqlite3',}
}# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validatorsAUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/LANGUAGE_CODE = 'en-us'TIME_ZONE = 'UTC'USE_I18N = TrueUSE_TZ = True# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/STATIC_URL = 'statics/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, "../statics"),
]# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-fieldDEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_HEADERS = ('*')

big_file_upload_backend/urls.py中的配置如下:

from django.contrib import admin
from django.urls import path
from big_file_upload_backend.views import checks, uploadurlpatterns = [path('admin/', admin.site.urls),path('api/check', checks),path('api/upload', upload),
]

big_file_upload_backend/views.py中的配置如下:

import json
import os
from django.http import JsonResponse
from big_file_upload_backend import settingsdef checks(request):if request.method == "POST":body = json.loads(request.body.decode("utf-8"))filename = body.get("sha256Promise", None)base_path = settings.STATIC_URL+'record_files/'+filename+'.txt'# base_path = '../statics/record_files/'+filename+'.txt'file_is_exits = os.path.exists(base_path)# 判断文件是否存在,存在则说明之前至少上传过一次if file_is_exits:with open(base_path, 'r') as f:check_list = json.loads(f.readline())else:# 不存在就返回空check_list = []return JsonResponse(check_list, safe=False)def upload(request):if request.method == "POST":# 注意这里用的是request.FILES 因为chunk为文件流形式chunk = request.FILES.get("chunk")# 当前的切片编号chunk_number = request.POST.get("chunkNumber")# 总切片数量chunks_total = int(request.POST.get("chunksTotal"))# 文件名唯一标识sha256_promise = request.POST.get("sha256Promise")# 文件名称filename = request.POST.get("filename")# base_path = '../statics/upload_files/'+sha256_promise # 这样写无效base_path = settings.STATIC_URL + "upload_files/" + sha256_promise  # 必须这样写# record_path中的txt文件用于记录已经上传过的切片record_path = settings.STATIC_URL + "record_files/" + sha256_promise+'.txt'  # 必须这样写os.makedirs(base_path, exist_ok=True)# 后缀名ext = filename.split(".")[-1]# 小切片的文件名称order_file = chunk_number+'.'+extfname = base_path+"/" + order_filewith open(fname, 'wb') as f:for line in chunk:# 将上传的文件写入小切片中,等上传完成后进行合并f.write(line)# 等写完了才做判断chunk_number_int = int(chunk_number)  # 将字符串转成intline_list = [int(chunk_number)]  # 默认先添加一个切片片段if os.path.exists(record_path):with open(record_path, 'r') as f:line_data = f.readline()  # 读取已经上传的小切片if line_data == '':passelse:line_list = json.loads(line_data)  # 将字符串形式的数组转为python数组if chunk_number_int not in line_list:line_list.append(chunk_number_int)  # 如果当前切片号不在已上传的数组中则添加with open(record_path, 'w') as f:f.write(json.dumps(line_list))  # 将已上传的片段列表重新写回记录文件中#  合并小切片片段段if len(line_list) == chunks_total:with open(base_path+"/"+filename, "wb") as f:# 按照升序一个一个合并for num in sorted(line_list):with open(base_path+"/"+str(num)+"."+ext, 'rb') as r:f.write(r.read())# 读取完毕将片段删除,只保留合并后的文件os.remove(base_path+"/"+str(num)+"."+ext)# 返回没啥用check_list = {"chunk_number": chunk_number, "code": 200}return JsonResponse(check_list)

在项目根目录下要新建一个statics目录,且其下边要有两个目录:

record_files
upload_files

最后分别运行前后端项目

前端:npm run dev
后端: python manage.py runserver

点击上传文件,选择一个较大的文件进行上传,可以看到右侧一直再分片上传,上传完成后会在上述两个文件中分别多出两个文件

在这里插入图片描述

如果是上传过程中还可以看到upload_files文件下的小分片中的片段产生和合并过程,也可以在上传到一半时随机关闭浏览器,下次打开重新上传,则会跳过之前上传的继续进行上传。上传完成后的效果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/891843.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MCP(Model Context Protocol)模型上下文协议 进阶篇3 - 传输

MCP 目前定义了两种标准的客户端-服务端通信传输机制&#xff1a; stdio&#xff08;标准输入输出通信&#xff09;HTTP with Server-Sent Events (SSE)&#xff08;HTTP 服务端发送事件&#xff09; 客户端应尽可能支持 stdio。此外&#xff0c;客户端和服务端也可以以插件方…

openai swarm agent框架源码详解及应用案例实战

文章目录 简介数据类型Agent类Response类Result类Swarm类run_demo_loop交互式会话 基础应用agent-handsofffunction-callingcontext_variablestriage_agent 高阶应用通用客服机器人(support bot)构建航班服务agent 参考资料 openai 在24年10月份开源了一个教育性质的多agents协…

【顶刊TPAMI 2025】多头编码(MHE)之极限分类 Part 2:基础知识

目录 1 预热1.1 记号1.2 分类器计算过载问题 2 多头编码&#xff08;MHE&#xff09;2.1 标签分解2.2 多头组合&#xff08;Multi-Head Combination&#xff09; 论文&#xff1a;Multi-Head Encoding for Extreme Label Classification 作者&#xff1a;Daojun Liang, Haixia …

攻防世界 - Misc - Level 1 | 适合作为桌面

关注这个靶场的其它相关笔记&#xff1a;攻防世界&#xff08;XCTF&#xff09; —— 靶场笔记合集-CSDN博客 0x01&#xff1a;考点速览 想要通过本关&#xff0c;你需要掌握以下知识点&#xff1a; Stegolve 查看图片隐写内容。 了解 pyc 文件&#xff0c;并知道如何通过 Wi…

Unity 从零开始的框架搭建1-3 关于命令模式的一些思考

Unity 从零开始的框架搭建1-2 事件的发布-订阅-取消的小优化及调用对象方法总结[半干货]-CSDN博客 本人水平有限 如有不足还请斧正&#xff0c;该文章专栏是向QFrameWork作者凉鞋老师学习总结得来&#xff0c;吃水不忘打井人&#xff0c;不胜感激 关于此模式我曾实现过&#…

UVM :uvm_sequence_item property and methods

transaction是uvm_sequence_item的一个子类。 topic transaction介绍 uvm_sequence_item override Set_type_override:同类型替换 Set_inst_override:同例化替换

SpringBoot原理分析-1

SpringBoot原理分析 作为一个javaer&#xff0c;和boot打交道是很常见的吧。熟悉boot的人都会知道&#xff0c;启动一个springboot应用&#xff0c;就是用鼠标点一下启动main方法&#xff0c;然后等着就行了。我们来看看这个main里面。 SpringBootApplication public class E…

前端(API)学习笔记(CLASS 4):进阶

1、日期对象 日期对象&#xff1a;用来表示事件的对象 作用&#xff1a;可以得到当前系统时间 1、实例化 在代码中发现了new关键字&#xff0c;一般将这个操作称为实例化 创建一个时间对象并获取时间 获得当前时间 const datenew Date() 使用日志查看&#xff0c;得到的…

力扣刷题:二叉树OJ篇(上)

大家好&#xff0c;这里是小编的博客频道 小编的博客&#xff1a;就爱学编程 很高兴在CSDN这个大家庭与大家相识&#xff0c;希望能在这里与大家共同进步&#xff0c;共同收获更好的自己&#xff01;&#xff01;&#xff01; 目录 1.单值二叉树&#xff08;1&#xff09;题目描…

4.1.2 栈和队列(二)

文章目录 队列的定义队列的基本运算队列的存储结构 队列的定义 队列先进先出&#xff0c;仅允许一端插入、一端删除 队尾(Rear)&#xff0c;插入 队头(Front)&#xff0c;删除 队列的基本运算 队列的基本运算 初始化空队列&#xff1a;initQueue(Q)判队空&#xff1a;isEmpty…

【HeadFirst系列之HeadFirst设计模式】第1天之HeadFirst设计模式开胃菜

HeadFirst设计模式开胃菜 前言 从今日起&#xff0c;陆续分享《HeadFirst设计模式》的读书笔记&#xff0c;希望能够帮助大家更好的理解设计模式&#xff0c;提高自己的编程能力。 今天要分享的是【HeadFirst设计模式开胃菜】&#xff0c;主要介绍了设计模式的基本概念、设计模…

Oracle数据库如何找到 Top Hard Parsing SQL 语句?

有一个数据库应用程序存在过多的解析问题&#xff0c;因此需要找到产生大量硬解析的主要语句。 什么是硬解析 Oracle数据库中的硬解析&#xff08;Hard Parse&#xff09;是指在执行SQL语句时&#xff0c;数据库需要重新解析该SQL语句&#xff0c;并创建新的执行计划的过程。这…

【GBT32960协议学习系列】GBT 32960协议的背景、目的和适用范围

GBT 32960协议的背景、目的和适用范围 1. GBT 32960协议的背景 GBT 32960是中国国家标准&#xff0c;全称为《电动汽车远程服务与管理系统技术规范》。该标准由中国国家标准化管理委员会发布&#xff0c;旨在规范电动汽车远程服务与管理系统的技术要求&#xff0c;确保电动汽车…

蓝桥杯备赛:C++基础,顺序表和vector(STL)

目录 一.C基础 1.第一个C程序&#xff1a; 2.头文件&#xff1a; 3.cin和cout初识&#xff1a; 4.命名空间&#xff1a; 二.顺序表和vector&#xff08;STL&#xff09; 1.顺序表的基本操作&#xff1a; 2.封装静态顺序表&#xff1a; 3.动态顺序表--vector&#xff1a;…

创建并配置华为云虚拟私有云

目录 私有云 创建虚拟私有云 私有云 私有云是一种云计算模式&#xff0c;它将云服务部署在企业或组织内部的私有基础设施上&#xff0c;仅供该企业或组织内部使用&#xff0c;不对外提供服务.私有云的主要特点包括&#xff1a; 私密性&#xff1a;私有云的资源&#xff08;如…

OWASP ZAP之API 请求基础知识

ZAP API 提供对 ZAP 大部分核心功能的访问,例如主动扫描器和蜘蛛。ZAP API 在守护进程模式和桌面模式下默认启用。如果您使用 ZAP 桌面,则可以通过访问以下屏幕来配置 API: Tools -> Options -> API。 ZAP 需要 API 密钥才能通过 REST API 执行特定操作。必须在所有 …

音视频入门基础:MPEG2-PS专题(3)——MPEG2-PS格式简介

一、引言 本文对MPEG2-PS格式进行简介。 进行简介之前&#xff0c;请各位先下载MPEG2-PS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-PS的官方文档。但是ITU提供的文档是免费的&#xff0c;ISO/IEC是付费的&#xff0c;所以我们主要阅读ITU提供的官方文档&#xff0c;比如较新…

CPT203 Software Engineering 软件工程 Pt.3 系统建模(中英双语)

文章目录 5. System Modeling&#xff08;系统建模&#xff09;5.1 Context models&#xff08;上下文模型&#xff09;5.2 Interaction models&#xff08;交互模型&#xff09;5.2.1 Use case modeling&#xff08;用况建模&#xff09;5.2.2 Sequence diagram&#xff08;顺…

什么是Kafka的重平衡机制?

Kafka 的重平衛机制是指在消费者组中新增或删除消费者时&#xff0c;Kafka 集群会重新分配主题分区给各个消费者&#xff0c;以保证每个消费者消费的分区数量尽可能均衡。 重平衡机制的目的是实现消费者的负载均衡和高可用性&#xff0c;以确保每个消费者都能够按照预期的方式…

Nginx——反向代理(三/五)

目录 1.Nginx 反向代理1.1.Nginx 反向代理概述1.2.Nginx 反向代理的配置语法1.2.1.proxy_pass1.2.2.proxy_set_header1.2.3.proxy_redirect 1.3.Nginx 反向代理实战1.4.Nginx 的安全控制1.4.1.如何使用 SSL 对流量进行加密1.4.2.Nginx 添加 SSL 的支持1.4.3.Nginx 的 SSL 相关指…