【场景方案】我所遇到的有关前端文件上传的知识点归纳,欢迎大家来补充

news2024/9/24 7:14:46

文章目录

  • 前言
  • 前后端传输的文件格式主要有哪些
    • base64
    • formData
  • 前端上传方案
    • input标签获取文件
    • HTML5的API
  • 切片上传大文件
  • blob数据转成base64
  • 未来不间断补充

前言

本文章总结了本人在网上和实际公司项目中遇到的有关前端文件上传功能的知识点,如有更好的方案或者发现错误,欢迎评论区中指出。

文章部分知识来源网上博客、gpt问答,以及b站up主【三十的前端课】的视频


前后端传输的文件格式主要有哪些

base64

base64编码只包含64个字符,它们由大小写字母、数字以及"+", "/"等特殊字符组成,但可以利用这64种字符来实现表示所有的字符。

为什么我们有时候在传输文本或者图片信息给后端时需要转成base64呢?

第一个原因

很多情况下前端的数据编码形式和后端的不一致,数据从一个编码转到另一个编码可能会出问题。例如前端传输的数据采用了UTF-8的编码方式,而后端使用的是GBK的编码方式,在传输的过程中就有可能导致数据传输错误或乱码,导致数据无法正常显示和处理。

当我们转成base64后,编码形式统一了。

那为啥偏偏是base64呢?不能是其他编码形式吗?因为base64很简单,就哪些常规的字符、字母,所以编码和解码的形式很简单,效率高。

第二个原因

如果需要对数据进行加密,加密后的数据也要面临不同编码形式的转换,也容易出现编码问题。当对base64的数据进行加密的时候,加密后的数据不会包含特殊字符和二进制码,能较少的出现编码问题。

缺点

base64也不是无敌的,他有以下缺点:

  • 转换后的数据明显多了
  • 后端拿到base64要有个解码的过程,对后端来说有点性能上的考虑

formData

这是一个可存有二进制blob的对象,当后端需要key-value的形式传递文件的时候,就可以采用这种方式。

使用方法:

let formDataObj = new FormData() // 实例化
formDataObj.append('fileKey', '123') // api的参数为key,value
formDataObj.append('file', file) // file为file对象的文件,下面会讲
console.log('FormData', formDataObj);
axiosApi(formDataObj) // 发送异步请求

当我们打印formData对象的时候,是看不到内容的

在这里插入图片描述
但是我们发起axios的post请求就可以看到
在这里插入图片描述
可以在请求头看到请求格式:
在这里插入图片描述
后面的表示每个key-value用什么字段区分开,可以在抓包工具中看完整的信息


前端上传方案

input标签获取文件

利用原生input标签就提供了文件上传的能力

<template>
    <div class="">
        <input type="file" @change="fileChange">
    </div>
</template>

<script setup>
const fileChange = (e) => {
    let file = e.target.files[0] // 单个文件,所以要取下标
    console.log('file', file);
}
</script>

把获取到的上传文件打印出来,可以看到是一个File类型的对象,这个对象中有这个文件的很多信息,例如大小,文件类型。里面的文件本体的存储应该是二进制,但打印是看不到的。

在这里插入图片描述

这个File对象是Blob对象的一个子类。都是二进制的存储形式,他们之间可以相互转换。

let blobFile = new Blob([file])
console.log('blobFile', blobFile);

let file = new File([blobFile], 'wenjianming.word')

在这里插入图片描述

HTML5的API

利用showDirectoryPicker()这个api可调出文件上传弹窗

const pickDirectory = async () => {
    const dirHandle = await window.showDirectoryPicker();
    for await (const entry of dirHandle.values()) {
        if (entry.kind === "file") {
            const file = await entry.getFile();
            const text = await file.text();
            console.log(text);
        }
        if (entry.kind === "directory") {
            /* for file in this directory do something */
        }
    }
}

目前发现两个问题:

  • 不知道为啥只能选整个文件夹,无法看到某个具体文件
  • 必须手动触发函数(例如按钮触发),如果是在例如生命周期这样的钩子中被动触发,会报错。

切片上传大文件

一个大文件上传给后端,过程可能会十分漫长,我们可以采用切分的方式,分步骤上传。

能被切片的对象有FIle与Blob

let sliceFile = file.slice(0, 3000) // file对象可以进行切割
let sliceBlobFile = blobFile.slice(0, 3000) // blob对象可以进行切割

例子:

const postApi = (file) => {
	let size = 2 * 1024 * 1024 // 每次切片的大小
	let fileSize = file.size // 文件总大小
	let current = 0 // 当前已上传大小
	while(current < fileSize) {
		let formData = new FormData()
		formData.append('fileName', file.name)
		formData.append('filekey', file.slice(current, current + size)) // key值给后端进行拼接的时候能够找对文件
		await axios.post('xxx/xx', formData)
		percent.value = Math.min((current / fileSize) * 100, 100) // 记录进度,取小,最大值100
		current += size
	}
}

如果上传到一半被中断了咋办?我们前端可以把每次的current存储在localStorage里面,网络恢复了,接续按照当前进度上传。

总结下切片上传的好处:

  • 可上传大文件,且性能能被考虑到
  • 能够知晓真实的进度
  • 能够支持断点续传

blob数据转成base64

我们可以借助FileReader对象,将一些量较小的二进制数据转成base64,例如切片数据。

// 将切片数据转成base64,可以借助FileReader对象
let fr = new FileReader()
fr.readAsDataURL(sliceBlobFile) // 调用api转换,但是是个异步操作,需要我们去监听
fr.onload = () => { // 异步监听
    let res = fr.result
    // 可以直接给img回显
}

// 这个对象还可以转换成文本信息
let frText = new FileReader()
frText.readAsText(sliceBlobFile) // 调用api转换,但是是个异步操作,需要我们去监听
frText.onload = () => { // 异步监听
    let res = fr.result
    // 可以直接放在标签中回显
}

未来不间断补充

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

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

相关文章

【Windows】【Audio】Windows 11 声音配置

目录 一. 问题 二. 步骤 三. 配置 3.1 候选列表 3.2 程序事件 3.2.1 Windows 3.2.2 文件资源管理器 3.2.3 Windows 语音识别 一. 问题 印象中记得 Windows XP 启动和关机&#xff0c;还有平常点击的过程中有声音来着&#xff0c;Windows 11 咋没有&#xff1f; 折腾了折…

智能优化算法:浣熊优化算法-附代码

智能优化算法&#xff1a;浣熊优化算法 文章目录 智能优化算法&#xff1a;浣熊优化算法1.浣熊优化算法1.1 初始化1.2 阶段一&#xff1a;狩猎和攻击&#xff08;探索阶段&#xff09; 2.实验结果3.参考文献4. Matlab 摘要&#xff1a;浣熊优化算法&#xff08;Coati Optimizat…

Mysql的可重复读解决了幻读问题吗

针对快照读&#xff08;普通 select 语句&#xff09;&#xff0c;是通过 MVCC 方式解决了幻读&#xff0c;因为可重复读隔离级别下&#xff0c;事务执行过程中看到的数据&#xff0c;一直跟这个事务启动时看到的数据是一致的&#xff0c;即使中途有其他事务插入了一条数据&…

开关电源基础02:基本开关电源拓扑(3)-拓扑分析

说在开头&#xff1a;关于薛定谔的波动方程&#xff08;1&#xff09; 当年毛头小子海森堡在哥廷根求学的时候&#xff0c;埃尔文.薛定谔已经是瑞士苏黎世大学的著名教授了。跟其他那些小天才&#xff08;定位精度&#xff1a;25岁5岁&#xff09;相比&#xff0c;薛定谔只能用…

使用 Python 查找本月的最后一天

文章目录 使用 Python 中的日历库查找月份的最后一天使用 Python 中的 DateTime 模块查找该月的最后一天从每个月的第一天减去一天以找到该月的最后一天使用存储在数组中的预加载日期使用 for 循环查找该月的最后一天打印日历年所有月份的最后一天以查找该月的最后一天 使用 Ar…

Kafka生产者原理

消息发送流程介绍 Producer创建时&#xff0c;会创建⼀个sender线程并设置为守护线程。⽣产消息时&#xff0c;内部其实是异步的&#xff1b;⽣产的消息先经过拦截器->序列化器->分区器&#xff0c;然后将消息缓存在缓冲区&#xff08;该缓冲区也是在Producer创建时创建…

关于clash退出后,华硕电脑连不上网了

关于clash退出后&#xff0c;华硕电脑连不上网了 问题记录 问题记录 昨天因为overleaf老断网&#xff0c;然后我就挂了一下clash&#xff08;第一次用&#xff0c;不怎么懂&#xff09;&#xff0c;后来直接关闭退出了。 今天早上突然浏览器的网页&#xff08;微软自带、华硕…

挑战14天学完Python----初识Python语法

往期文章 Java继承与组合 你知道为什么会划分数据类型吗?—JAVA数据类型与变量 10 &#xff1e; 20 && 10 / 0 0等于串联小灯泡?—JAVA运算符 你真的知道怎样用java敲出Hello World吗&#xff1f;—初识JAVA 目录 往期文章前言1.温度转换实例2. 程序格式框架2.1 高…

ATT汇编快速学习

说明 文档来源 https://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html 使用AT&T语法; 原文档是intel语法翻译过来的; 内容 基于32位, x86的硬件环境; 指令仅仅介绍常用, 即还有很大一部分的指令并没有支持; 编译器(汇编器) GAS(GNU assembler: 即gnu组织提供; 使…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 5 Link Analysis

来源&#xff1a;《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 5 Link Analysis Terms: words or other strings of characters other than white space. An inverted index is a data structure that makes it easy, given a term, to find (pointers to) a…

【数码】收音机,德生PL380使用教程与注意事项

文章目录 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09;2、电池和电池模式的匹配3、收音机天线与信号&#xff0c;耳机与噪音F、参考资料 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09; 红色的按钮&#xff1a;power 按一下开机&#xff0c;按…

DJYOS开源往事一:djyos爱好者大南山相聚写实

前言&#xff1a;DJYOS开源社区成立于2009年&#xff0c;后因为专注技术方向和垂直产业化等原因&#xff0c;2015年后关闭开源社区。斗转星移&#xff0c;DJYOS开源社区虽然关闭&#xff0c;但是DJYOS开源和精神依然在&#xff0c;转眼DJYOS发布十四年了。记录一下DJYOS开源往事…

Qt Plugin插件开发

一、Qt 插件机制 .1 Qt 插件简介 插件是一种遵循一定规范的应用程序接口编写出来的程序&#xff0c;定位于开发实现应用软件平台不具备的功能的程序。插件与宿主程序之间通过接口联系&#xff0c;就像硬件插卡一样&#xff0c;可以被随时删除&#xff0c;插入和修改&#xff…

2.2.4 Linux安装模式下,磁盘分区的选择(重要)

目录树结构 &#xff08;directory tree&#xff09; 整个Linux系统最重要的地方就是在于目录树架构。 所谓的目录树架构&#xff08;directory tree&#xff09;就是以根目录为主&#xff0c;然后向下呈现分支状的目录结构的一种文件架构。 所以&#xff0c;整个目录树架构最重…

Midjourney-Discord入门+高手指引手册

上一篇我们说了如何注册和订阅&#xff0c;今天我们来讲一讲相关的细节&#xff0c;首先我们来一个概览图&#xff0c;先有个大致的印象。 概览图 生成的四张图片&#xff0c;类似于Demo&#xff0c;从左至右&#xff0c;从上至下&#xff0c;1,2,3,4放大按钮U1&#xff0c;U2…

【旋转编码器如何工作以及如何将其与Arduino一起使用】

在本教程中,我们将学习旋转编码器的工作原理以及如何将其与Arduino一起使用。您可以观看以下视频或阅读下面的书面教程。 1. 概述 旋转编码器是一种位置传感器,用于确定旋转轴的角度位置。它根据旋转运动产生模拟或数字电信号。 有许多不同类型的旋转编码器按输出信号或传感…

三个令人惊艳超有用的 ChatGPT 项目,开源了!

自 3 月初 Open AI 开放 ChatGPT API 以来&#xff0c;GitHub 上诞生的开源项目数量之多&#xff0c;着实多得让我眼花缭乱、应接不暇。 今天&#xff0c;我将着重挑选几个对日常工作、生活、学习帮助较大的 ChatGPT 开源项目&#xff0c;跟大家分享下&#xff0c;希望对你有所…

Illustrator如何使用填充与线条之实例演示?

文章目录 0.引言1.绘制星空小插画2.制作清新小碎花壁纸3.双重描边文字 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对Illustrator进行了学习&#xff0c;本文通过《Illustrator CC2018基础与实战》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对…

labelme标注数据集,并利用paddleseg完成标注数据的准备工作

1、安装labelme 1、创建labelme虚拟环境 先检查python的版本 python -V使用命令 conda create -n labelme python=3.9,创建虚拟环境 2、激活虚拟环境 conda activate labelme3、安装labelme pip install labelme2、labelme的使用 1、打开cmd输入命令 labelme2、进入label…

关于安装Node/Yarn/Electron过程中遇到的问题

目录 1、安装Node2、安装electron很慢3、PowerShell中无法使用yarn命令4、Yarn命令目录bin与其全局安装位置不在同一个文件夹 1、安装Node 【参考文章】Node.js下载安装及环境配置教程 2、安装electron很慢 npm config set electron_mirror https://npm.taobao.org/mirrors/…