前端文件上传

前言:本文章的第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
	}
  });
相关推荐
之歆14 分钟前
DAY08_CSS浮动与行内块布局实战指南(下)
前端·css
yqcoder32 分钟前
CSS Position 全解析:5 种定位模式详解
前端·css
Rhi6371 小时前
从零搭建项目:React 19 + Vite 8 + Tailwind CSS v4 实战配置
前端
竹林8181 小时前
用Viem替代ethers.js:从一次签名失败到完整迁移的实战记录
前端·javascript
之歆1 小时前
DAY08_CSS浮动与行内块布局实战指南(上)
前端·css
light blue bird2 小时前
主子端台二分法任务汇总组件
前端·数据库·.net·桌面端winform
不可能的是3 小时前
Claude Code 子 Agent 机制全解:怎么跑起来、怎么被管理、怎么互不干扰
javascript
jeffwang3 小时前
我做了个让 AI 看屏幕跑测试的工具,因为 Playwright 测不了我的 Flutter Web
前端
HSunR3 小时前
dify 搭建ai作业批改流
开发语言·前端·javascript
代码不加糖3 小时前
2026 跨境电商独立站实战:从 0 到 1 搭建高转化 SaaS 商城(附源码)
开发语言·前端·javascript