吃透前端文件上传与文件相关操作 多文件上传 大文件切片上传 拖拽上传 后续还会更新 断点续传等等

news2024/11/13 15:59:01

最近在学文件上传的操作,所以想把学习到东西写成一文章
这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的
前端文件上传 我首先想到是

<input type="file">**选择文件**</input>

如果我们想限制上传文件的格式,大小或进行裁剪分片上传

如何对文件上传进行操作呢

查阅mdn文档 发现三个可用于type=“file”的属性
accept 文件上传控件中预期文件类型的提示
capture 文件上传控件中媒体捕获方法的提示

  • capture="camera":用户将直接进入摄像头捕获界面,可以拍摄照片或录制视频。
  • capture="user":用户将进入相册,可以从相册中选择照片或视频。
  • multiple 布尔值。是否允许多个值 默认为false
<input type="file" accept="image/*" multiple>选择文件</input>

额。。。。。。好像并没有解决问题
换另一个办法,可以使用 File 对象的属性

<input type="file" id="fileInput" ></input>

<script>

const fileInput = document.getElementById('fileInput');

fileInput.addEventListener('change', function(event) {

const file = event.target.files[0];

console.log('文件名:', file.name);

console.log('文件大小:', file.size);

console.log('文件类型:', file.type);

});

</script>

这次获取到可以操作对象的属性
这下可以实现一些简单的需求 比如约束文件格式,约束文件大小

 if(file.size > 10 * 1024 *1024){

 alert('不能超过10M')

 }
 if(file.type !=='image/jpeg'){

 alert('必须为jpeg图片')

 }

那么如何实现文件内容的操作呢

想要操作文件的内容 先获取文件的内容

如何读取文件内容

JS中提供了API。可以使用 FileReader对象读取文件内容,然后进行处理。,常见的转换方法包括readAsText()readAsDataURL(),readAsArrayBuffer()
如何使用

  • 如果需要将文件内容解析为文本形式,可以使用 readAsText(file)
  • 如果需要处理文件的二进制数据,可以使用 readAsArrayBuffer(file)
  • 如果需要在页面中显示文件内容或生成可用于展示的 URL,可以使用 readAsDataURL(file)
    下列代码用常用的base64举例
const fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(event) {
const file = event.target.files[0]

const reader = new FileReader();

//解析成 Base64
reader.readAsDataURL(file);

reader.onload = function(e) {

const fileContent = e.target.result;
//const fileContent= reader.result;

console.log('文件内容:', fileContent);

};

});

前端给后端传输文件的格式

前端给后端的文件一般都是二进制blob传输或base64传输格式,前端给后端上传文件

什么是blob对象呢

Blob对象是用来表示二进制数据的一个接口,可以存储大量的二进制数据

mdn上解释

要从其他非 blob 对象和数据构造一个 Blob,请使用 Blob 构造函数。要创建一个 blob 数据的子集 blob,请使用 slice() 方法。
语法 new Blob(array, options)
File对象
new File()
new File(bits, name[, options])
bits一个包含ArrayBuffer,ArrayBufferView,Blob,或者 DOMString 对象的Array — 或者任何这些对象的组合。这是 UTF-8 编码的文件内容。

现在可以运用了解的知识 可以做一个缩略图了用vue实现下

<template>
<input type="file" name="file" @change="fileChange">选择文件</input>
<img :src="imgbase64" style="width:800px"/>
</template>
<script setup>
const imgbase64 = ref()
const fileChange = (e:any) => {
//这最好做个浅拷贝 直接在原对象上面操作不好
let file = e.target.file
let _sliceBlob = new Blob([__file]).slice(0,5000)
let _sliceFile = new File([_sliceBlob],"text.jpeg")
let fr = new FileReader()
// 转换成base64
fr.readAsDataURL(_sliceFile)
fr.onload = function(){
imgbase64.value = fr.result
}
}
</script>

如何上传到后端

FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。
你可以使用FormData.append来添加键/值对到表单里面

Submitbtn.addEventListener('click',() => {

let _formData = new FormData()

let data = _formData.append(_file.name+'file',_file)

axios.post("/xx",data)

})

接下来代码用Vue实现 基础文件上传操作已经完成 接下来是些小功能

如何实现多文件上传

正常方案应该是直接在input里面加入multiple

<input type="file" multiple></input>

这样就可以直接ctrl+鼠标左键就可以多选 但明显不符合日常多文件上传的习惯 有些人喜欢一个一个选 而且需要把多文件上传的名字 “两个文件” 改成 两个文件各自名字好些
接下来实现一波 无非就是定义一个数组,将之前的值存里面

<template>

<input type="file" name="file" @change="fileChange" multiple >选择文件</input>

<span v-for="item in imgList" :key="item">{{item.name}} </span>

<button @click="sumbit">文件按钮</button>

</template>
<script setup lang="ts">
import { ref } from 'vue';
const imgList = ref([])
let file = e.target.files[0]

__file = file

e.target.files.length > 1 ? imgList.value.push(...e.target.files) : imgList.value.push(e.target.files[0])	

const sumbit =async () => {

imgList.value.forEach((item) => {

let _formData = new FormData()

console.log(item)

let data = _formData.append(item.name + 'file',item)

axios.post("/xx",data)

})
</script>

多文件上传就实现了
请添加图片描述

大文件切片上传

为什么要切片上传

避免上传超时:大文件可能会导致上传时间过长,从而触发服务器超时或网络中断。切片上传将大文件分解成小块,每块上传时间较短,能有效减少超时问题。

支持断点续传:如果上传过程中发生错误(如网络中断),只有当前切片需要重新上传,而不是整个文件。这大大减少了重新上传的工作量和时间。

减少内存占用:在上传过程中,服务器可以逐个处理小块数据,减少对内存的需求,而不是一次性接收整个大文件。

实现大文件切片上传步骤
1.获取上传文件对象
2.创建分片数据
3.分片数据创建内容
4.调用发送分片的接口
<!DOCTYPE html>

<html lang="en">

<body>

<script src="

https://cdn.jsdelivr.net/npm/spark-md5@3.0.2/spark-md5.min.js

"></script>

<input id="inputBox" type="file" multiple></input>

<script>

var inputs = document.getElementById('inputBox')

inputs.onchange = async function(){

// 获取到上传文件对象

let file = inputs.files[0]

//创建分片数据

let chunks = createChunk(file,50*1024*1024)

//分片数据创建内容

let res = await createhash(chunks)

//调用发送分片的接口

uploadChunk(chunks,res,file.name)

}

function createChunk(file, chunkSize){

const result = []

for(let i=0; i< file.size; i+=chunkSize){

result.push(file.slice(i, i + chunkSize))

}

return result

}

function createhash(chunks){

return new Promise((resolve) => {

let spark = new SparkMD5()

function _read(i){

if(i >= chunks[i]){

resolve(spark.end())

return

}

//获取当前其中的一个片段

let blob = chunks[i]

// 创建一个FileReader对象

let reader = new FileReader()

reader.onload = e => {

let bytes = e.target.result

spark.append(bytes)

_read(i+1)

}

reader.readAsArrayBuffer(blob)

read(i+1)

}

_read(0)

})

}

function uploadChunk(chunks,hash,fileName){

let taskArr = []

chunks.forEach((chunk,index) => {

let formdata = new FormData()

formdata.append('chunk',chunk)

formdata.append('chunkName',`${hash}-${index}-${fileName}`)

fromdata.append('fileName',fileName)

let task = axios.post('http://127.0.0.01/xxx/xxx', fromdata,{

headers:{

'Content-Type:':'multipart/form-data'

}

})

taskArr.push(task)

})

  

Promise.all(taskArr).then(() => {

console.log('通知后端')

})

}

</script>

</body>

  

</html>

拖拽上传

请添加图片描述

步骤
设置拖拽区域:创建一个可拖拽的区域,通常通过设置一个带有边框和中心提示的 HTML 元素来完成。
处理拖拽事件:监听拖拽相关事件,如 dragenterdragoverdragleavedrop。这些事件帮助你控制拖拽区域的样式变化(例如,当文件拖入时改变边框颜色),并防止默认行为(如浏览器默认打开文件)。
接下来就是老步骤了

<div class="drag-area">

<div class="icon"><i><svg t="1720077078914" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3421" width="200" height="200"><path d="M1022.955204 522.570753c0 100.19191-81.516572 181.698249-181.718715 181.698249l-185.637977 0c-11.2973 0-20.466124-9.168824-20.466124-20.466124 0-11.307533 9.168824-20.466124 20.466124-20.466124l185.637977 0c77.628008 0 140.786467-63.148226 140.786467-140.766001 0-77.423347-62.841234-140.448776-140.203182-140.766001-0.419556 0.030699-0.818645 0.051165-1.217734 0.061398-5.945409 0.143263-11.686157-2.292206-15.687284-6.702656-4.001127-4.400217-5.894244-10.335393-5.167696-16.250102 1.330298-10.806113 1.944282-19.760043 1.944282-28.192086 0-60.763922-23.658839-117.884874-66.617234-160.833035-42.968627-42.968627-100.089579-66.617234-160.843268-66.617234-47.368844 0-92.742241 14.449084-131.208321 41.781592-37.616736 26.738991-65.952084 63.700811-81.925894 106.884332-2.425236 6.538927-8.012488 11.399631-14.827707 12.893658-6.815219 1.483794-13.927197-0.603751-18.859533-5.54632-19.289322-19.330254-44.943608-29.972639-72.245418-29.972639-56.322773 0-102.146425 45.813419-102.146425 102.125959 0 0.317225 0.040932 0.982374 0.092098 1.627057 0.061398 0.920976 0.122797 1.831718 0.153496 2.762927 0.337691 9.465582-5.863545 17.928325-15.001669 20.455891-32.356942 8.933463-61.541635 28.550243-82.181721 55.217602-21.305235 27.516704-32.571836 60.508096-32.571836 95.41307 0 86.244246 70.188572 156.422585 156.443052 156.422585l169.981393 0c11.2973 0 20.466124 9.15859 20.466124 20.466124 0 11.2973-9.168824 20.466124-20.466124 20.466124l-169.981393 0c-108.828614 0-197.3753-88.536452-197.3753-197.354833 0-44.053332 14.223956-85.712127 41.126676-120.473839 22.809495-29.460985 53.897537-52.086285 88.710414-64.816215 5.065366-74.322729 67.149353-133.2447 142.751215-133.2447 28.386514 0 55.504128 8.217149 78.651314 23.52581 19.657712-39.868009 48.842405-74.169233 85.497233-100.212376 45.434795-32.295544 99.004875-49.354058 154.918325-49.354058 71.692832 0 139.087778 27.915793 189.782368 78.600149 50.694589 50.694589 78.610382 118.089535 78.610382 189.782368 0 3.704368-0.102331 7.470135-0.296759 11.368932C952.633602 352.568894 1022.955204 429.511287 1022.955204 522.570753z" p-id="3422" fill="#cdcdcd"></path><path d="M629.258611 820.711014l-102.023628 102.013395c-3.990894 4.001127-9.230222 5.996574-14.46955 5.996574s-10.478655-1.995447-14.46955-5.996574l-102.023628-102.013395c-7.992021-7.992021-7.992021-20.947078 0-28.939099s20.947078-8.002254 28.939099 0l67.087954 67.077721 0-358.699522c0-11.2973 9.15859-20.466124 20.466124-20.466124 11.307533 0 20.466124 9.168824 20.466124 20.466124l0 358.699522 67.087954-67.077721c7.992021-8.002254 20.947078-7.992021 28.939099 0S637.250632 812.718993 629.258611 820.711014z" p-id="3423" fill="#cdcdcd"></path></svg></i></div>

<header>Drag & Drop to Upload File</header>

<span>OR</span>

<button>Browse file</button>

<input type="file" hidden>

</div>

js部分

const dragArea = document.querySelector(".drag-area")

dragText = dragArea.querySelector('header')

button = dragArea.querySelector('button')

input = dragArea.querySelector('input')

let file;

button.onclick = function () {

input.click()

}

input.addEventListener('change',() => {

file = this.files[0]

showFile()

})

dragArea.addEventListener('dragover',(event) => {

event.preventDefault();

dragArea.classList.add("active")

})

dragArea.addEventListener('dragleave',() => {

console.log('222')

dragArea.classList.remove("active")

})

dragArea.addEventListener('drop',(event) => {

event.preventDefault();

console.log('222')

file = event.dataTransfer.files[0]

showFile()

})

function showFile(){

let fileType = file.type

const validFiletype = ['image/jpeg','image/jpg',"image/png"]

if(validFiletype.includes(fileType)){

let fileReader = new FileReader()

fileReader.onload = () => {

fileReader = fileReader.result;

let imgTag = `<img src="${fileReader}" alt="">`

dragArea.innerHTML = imgTag

}

fileReader.readAsDataURL(file)

}else{

console.log('不规则的')

}

}

css部分

*{

margin:0;

padding:0;

box-sizing: border-box;

}

  

body{

display:flex;

align-items: center;

justify-content: center;

min-height: 100vh;

background-color: #5256ad;

}

.drag-area{

border: 2px dashed #fff;

height: 500px;

width:700px;

border-radius: 5px;

display:flex;

align-items: center;

justify-content: center;

flex-direction:column;

}

.drag-area .active {

border: 2px solid #fff;

}

.drag-area .icon{

width:100px;

height:100px;

}

.drag-area header {

font-size:30px;

font-weight:500;

color:#fff;

}

.drag-area span{

font-size:25px;

font-weight:500;

color:#fff;

margin:10px 0 15px 0 ;

}

.drag-area button{

padding:10px 25px;

font-size:20px;

font-weight:500;

border:none;

outline:none;

background-color: #fff;

color:#5256ad;

border-radius: 5px;

cursor:pointer

}

.drag-area img {

height:100%;

width:100%;

object-fit: cover;

border-radius: 5px;

}

如果对你有所帮助的话就点个关注吧

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

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

相关文章

产品经理-如何判断一个产品的好与坏(36)

当面试官问到,如何判断一个产品的好与坏时,该怎么回答,这个问题非常综合地考查了你对产品的理解&#xff0c;但是题目本身非常大且难有标准答案 即使是面试官也不敢说能答好这道题。求职者在遇到这种很开放的题目时&#xff0c;如果不假思索就开答&#xff0c;往往是很危险的。…

在亚马逊云科技上搭建云原生生成式AI教育学习平台

项目简介&#xff1a; 小李哥将继续每天介绍一个基于亚马逊云科技AWS云计算平台的全球前沿AI技术解决方案&#xff0c;帮助大家快速了解国际上最热门的云计算平台亚马逊云科技AWS AI最佳实践&#xff0c;并应用到自己的日常工作里。 本次介绍的是如何利用亚马逊云科技大模型托…

【python】Python中subprocess模块的参数解读以及应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

如何用AI技术运营漫画推文,实现轻松变现

最近&#xff0c;漫画推文在各大平台上特别火&#xff0c;加上AI技术的加持&#xff0c;现在大家都有机会分一杯羹。今天我就来详细聊聊&#xff0c;如何利用AI技术来运营漫画推文&#xff0c;实现轻松变现。 项目介绍 咱们先来了解一下这个项目到底是啥。漫画推文&#xff0c;…

流量池是什么?萤石物联网卡流量池使用指南

要将4G设备通过萤石开放平台上云&#xff0c;有单卡模式/流量池两种使用模式&#xff0c;以下介绍流量池功能的使用方法 一、账号注册和登录 打开 萤石开放平台官网登录您的账号。若您还没有账号&#xff0c;请注册 二、申请物联网卡 登录后进入物联网卡申请页面没有卡的情况下…

【FreeRTOS】队列实验-多设备玩游戏(红外改造)

目录 0 前言1. 队列实验_多设备玩游戏2 回顾程序3 程序改进3.1 创建队列3.1.1 方法3.1.2 实践 3.2 读队列3.2.1 方法3.2.2 实践 3.3 写队列3.3.1 方法3.3.2 实践 0 前言 学习视频&#xff1a; 【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS&#xff08;FreeRTOS教程 基…

WPS真题题库导入刷题小程序:百思考个人使用经验分享

这篇文章的诞生&#xff0c;是因为我即将踏上一场超级有趣的挑战——备考全国计算机等级二级WPS Office高级应用与设计的冒险之旅&#xff01; WPS的分值&#xff1a; 单项选择题20分(含公共基础知识部分10分)。 WPS处理文字文档操作题30分。 WPS处理电子表格操作题30分。 …

Taro+Vue 创建微信小程序

TaroVue 创建微信小程序 一、全局安装 tarojs/cli二、项目初始化三、现在去启动项目吧 一、全局安装 tarojs/cli npm install -g tarojs/cli //安装 npm info tarojs/cli //查看安装信息 如果正常显示版本说明成功了&#xff0c;就直接跳到第二步吧官网说&#xff1a;…

如何快速自学开源项目?试试我的诀窍

大家好&#xff0c;我是程序员鱼皮。上周二晚上我直播带大家学习了一个 GitHub 上不错的开源聊天室项目 MallChat &#xff0c;大家表示学到了很多&#xff0c;所以我专门剪出了一期项目导学视频&#xff0c;分享给大家&#xff1a; https://www.bilibili.com/video/BV1Q142147…

Redis 高可用性如何实现?

Redis 高可用性如何实现&#xff1f; 1、主备切换2、哨兵集群 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; Redis&#xff0c;作为广泛使用的内存数据结构存储系统&#xff0c;通过一系列机制和策略&#xff0c;如主备切换、哨兵&#xf…

vue脚手架配置代理(解决跨域问题)

vue配置代理 一.介绍二.方法一三.方法二 一.介绍 跨域问题是指协议&#xff0c;主机&#xff0c;端口有一个以上不同 解决方法&#xff1a; 1&#xff0c;cors(最标准&#xff09; 2&#xff0c;jsonp&#xff08;script src&#xff09;&#xff08;比较巧妙&#xff09; 3&a…

使用MongoDB构建AI:Story Tools Studio将生成式AI引入Myth Maker AI游戏

Story Tools Studio利用先进的生成式AI技术&#xff0c;打造沉浸式、个性化、无穷尽的情景体验。 Story Tools Studio创始人兼首席执行官Roy Altman表示&#xff1a;“我们的旗舰游戏Myth Maker AI采用的是我们自主研发的、以AI为驱动的专家指导型故事生成器MUSE&#xff0c;它…

跨境电商新手必知:轻松解决商品详情图一键翻译难题!

在做跨境电商&#xff0c;商品详情图的翻译是至关重要的一环。 对于刚刚踏上跨境电商之旅的个人创业者来说&#xff0c;如何实现一键翻译商品详情图&#xff0c;可能是一个令人头疼的问题。 别担心&#xff0c;现在有许多实用的工具和方法可以帮助您轻松应对。 比如&#xff…

使用Windows11搭建代理服务器

一、问题引入二、下载并安装apache服务器三、配置Apache服务四、安装服务并测试五、文中提到的下载文件集合一、问题引入 使用ccproxy总是有很多限制,而且总是中断,因此就想自己用windows搭建一个。 二、下载并安装apache服务器 进入apache官网https://httpd.apache.org/do…

C/C++实现蓝屏2.0

&#x1f680;欢迎互三&#x1f449;&#xff1a;程序猿方梓燚 &#x1f48e;&#x1f48e; &#x1f680;关注博主&#xff0c;后期持续更新系列文章 &#x1f680;如果有错误感谢请大家批评指出&#xff0c;及时修改 &#x1f680;感谢大家点赞&#x1f44d;收藏⭐评论✍ 前…

在使用JMeter做负载测试遇到过的坑

1、本人做的是HTTP测试。遇到一个错误提示 415 not suported mediatype 注意&#xff0c;需要添加一个HTTP信息头管理信息&#xff0c;在运行的时候&#xff0c;请保持它启动是启用状态。 添加步骤如下图。 相关配置信息如下图。因为采用了JWTTOKEN进行权限验证&#xff0c…

SQL面试题练习 —— 有序行转列

目录 1 题目2 建表语句3 题解 1 题目 有学生各学科分数表&#xff0c;记录了学生的各科分数&#xff0c;请按照学生粒度&#xff0c;生成两列数据分别为学科和分数&#xff0c;要求学科内的顺序与分数顺序一致。 样例数据 期望结果 2 建表语句 --建表语句 create table if not…

偶然遇到了scanf输入字符时,前面与要加上空格

任务描述 本关任务&#xff1a;给定一个含有n个学生数据元素的数组a&#xff0c;用头插法来快速创建整个单链表。 相关知识 创建单链表有两种方法&#xff1a; 先初始化一个单链表&#xff0c;然后向其中一个一个地插入元素&#xff0c;通过调用基本运算算法来创建单链表。…

基于springboot-vue的毕业论文管理系统

TOC springboot251基于springboot-vue的毕业论文管理系统 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化…

海康VisionMaster使用学习笔记1-本地图像导入及参数设置

前言 原计划直接学习海康相机二次开发,发现先学习使用海康VisionMaster很有必要,与其他相机工具还有用法不太相同.开始记录一下海康VisionMaster使用学习笔记. 本地图像导入及参数设置 本地图像导入 在工具箱中找到采集 拖取图像源模块到流程编辑区域 双击图像源,选择图像源…