前端文件上传

前言:本文章的第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
	}
  });
相关推荐
灵感__idea3 小时前
Hello 算法:贪心的世界
前端·javascript·算法
GreenTea5 小时前
一文搞懂Harness Engineering与Meta-Harness
前端·人工智能·后端
killerbasd6 小时前
牧苏苏传 我不装了 4/7
前端·javascript·vue.js
吴声子夜歌7 小时前
ES6——二进制数组详解
前端·ecmascript·es6
码事漫谈7 小时前
手把手带你部署本地模型,让你Token自由(小白专属)
前端·后端
ZC跨境爬虫7 小时前
【爬虫实战对比】Requests vs Scrapy 笔趣阁小说爬虫,从单线程到高效并发的全方位升级
前端·爬虫·scrapy·html
爱上好庆祝7 小时前
svg图片
前端·css·学习·html·css3
橘子编程7 小时前
JavaScript与TypeScript终极指南
javascript·ubuntu·typescript
王夏奇8 小时前
python中的__all__ 具体用法
java·前端·python
叫我一声阿雷吧8 小时前
JS 入门通关手册(45):浏览器渲染原理与重绘重排(性能优化核心,面试必考
javascript·前端面试·前端性能优化·浏览器渲染·浏览器渲染原理,重排重绘·reflow·repaint