前端文件上传

前言:本文章的第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
	}
  });
相关推荐
miss27 分钟前
AI 改完不敢上线?OpenSpec 规约驱动开发实战
前端·代码规范·前端工程化
AiMan1 小时前
腾讯ima还是不可以导出左侧所有对话,只能单条导出,方法不对吗
前端
去伪存真1 小时前
并发量一高就装死?Agent 全链路“防猝死”手册
前端·agent
Moment1 小时前
AI 编程时代,聊聊我的 Mac mini 双屏桌面
前端·后端
AiMan1 小时前
先确认能不能一次把Microsofat Copilot所有内容打包一个文件导出
前端
总要学点什么1 小时前
第97篇:三维数据加载-城市建筑白模自定义着色器——让一条光带沿高度扫上去,快慢却由帧率说了算
前端·gis·webgl·cesium·着色器·空间分析·白模
上海懒图科技2 小时前
工厂厂区电子地图定位导航:厂区人车精准定位,安全合规双保障
前端·arcgis·vue
西安小哥2 小时前
端侧跑大模型,真正的门槛不在参数量:一次 596 秒到 10 秒的压缩路径复盘
前端·人工智能
陈随易3 小时前
Cloudflare 出钱,Vite 团队挑人,44 个维护者分 30 万美元
前端·后端·程序员
恋猫de小郭3 小时前
Flutter THLC 的 WebView 滚动终于从 70 FPS 提升到 120 FPS
android·前端·flutter