前端文件上传

前言:本文章的第5、6条实例代码没进行运行校验,有错勿见怪

一、文件上传的两种主要方式

1、二进制blob上传(使用formData对象搭载二进制数据传给后端)

2、base64编码上传(使用fileReader对象把数据转换为base64格式的数据传给后端)

二、文件上传的相关对象

1、file:通过input标签获取的文件对象;

2、blob:不可变的二进制内容,包含很多操作方法;

3、FormData:用于和后端传输的对象(相当于一个货车);

4、fileReader:多用于把文件读取为某种形式,比如使用readAsDataURL()转化为base64格式、使用text文本。

注意:file是blob的一个子类,所以blob上面的方法file对象都有,我们不能把file对象中的文件信息直接传给后端,只能借助FormData对象去上传,把文件以二进制的形式传给后端。关系图如下

三、实例

1、file对象和blob对象可以相互转换

javascript 复制代码
<div class="cont">
  <input type="file" class="file" />
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", (e) => {
    const file = e.target.files[0];
    const _blob = new Blob([file]);
    const _file = new File([_blob], "1.png");
    console.log(file, _blob, _file);
  });
</script>

运行结果如下

2、实现缩略图展示(转成base64格式)

javascript 复制代码
<div class="cont">
  <input type="file" class="file" />
  <img src="" class="img" style="width: 100px; height: 100px" />
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", (e) => {
	const file = e.target.files[0];
	// 将文件转为base64格式
	const reader = new FileReader();
	reader.readAsDataURL(file);
	reader.onload = (res) => {
	  const imgEl = document.querySelector(".img");
	  imgEl.setAttribute("src", res.target.result);
	};
  });
</script>

选中图片后

这时候我们能看到图片的地址已被转换成base64格式

3、转换成base64格式上传

javascript 复制代码
<div class="cont">
  <input type="file" class="file" />
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", (e) => {
	const file = e.target.files[0];
	const fr = new FileReader()
	// 将文件转为base64格式
	fr.readerAsDataURL(file)
	fr.onload = (res) => {
	  const finalRes = res.target.result
	  // 以下使用finalRes作为参数进行ajax请求...
    }
  });
</script>

4、blob流上传

javascript 复制代码
<div class="cont">
  <input type="file" class="file" />
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", (e) => {
	const file = e.target.files[0];
	const fd = new FormData()
	fd.append("file", file)
	// 以下使用fd作为参数进行ajax请求...
  });
</script>

5、多文件上传

以上3、4实例实现的是单文件上传,如果我们要实现多文件上传则要在input标签中加入multiple属性,其实本质就是遍历单文件上传。

javascript 复制代码
<div class="cont">
  <input type="file" class="file" multiple />
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", (e) => {
	const files = e.target.files;
	if (files && files.length) {
	  files.forEach(ele => {
	    const fd = new FormData()
	    fd.append(ele.name, ele)
	    // 以下使用fd作为参数进行ajax请求...
	  })
	}
  });

6、分片上传

其实很好理解,就是按照file对象返回的size属性进行切割上传。比如选择的文件是100M,我们按照每段2M的大小对文件进行切割,然后遍历上传。如下面代码:

javascript 复制代码
<div class="cont">
  <input type="file" class="file" />
  <-- 展示上传进度 -->
  <div class="process"></div>
</div>

<script>
  const el = document.querySelector(".file");
  el.addEventListener("change", async (e) => {
	const file = e.target.files[0];
	// 当前进度
	let process = 0
	// 文件总大小
	const fileSize = file.size
	// 每段文件字节大小
	const sectionSize = 2 * 2024 * 2024
	// 当前已传文件字节大小
	let currentSize = 0
	while(currentSize < fileSize) {
	  const fd = new formData()
	  fd.append(file.name, file.slice(currentSize, currentSize+sectionSize))
	  await // 此后使用fd作为参数进行ajax请求...
	  process = Math.min(Math.cell((currentSize / fileSize) * 100, 100))
	  currentSize += sectionSize
	}
  });
相关推荐
恋猫de小郭2 小时前
Tailwind 因为 AI 的裁员“闹剧”结束,而 AI 对开源项目的影响才刚刚开始
前端·flutter·ai编程
要加油哦~2 小时前
算法 | 整理数据结构 | 算法题中,JS 容器的选择
前端·javascript·算法
一只小bit2 小时前
Qt 重要控件:多元素控件、容器类控件及布局管理器
前端·c++·qt
一 乐10 小时前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕11 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫11 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo11 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo12 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq12 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js