前端文件上传

前言:本文章的第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
	}
  });
相关推荐
随风一样自由3 小时前
【前端独角兽】刚进入前端领域的前端开发用jQuery还是Vue3?
前端·javascript·vue3·jquery
IMPYLH4 小时前
HTML 的 <data> 元素
前端·html
YHHLAI4 小时前
[特殊字符] 面试中的 Promise —— 从入门到精通
前端·javascript·面试
weixin_BYSJ19875 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
沪飘大军6 小时前
ll-llm:一个零依赖、可插拔的 OpenAI 兼容 LLM 代理
javascript
kyriewen6 小时前
我扒了 GPT-5.6 的全部编程跑分——有一项 OpenAI 没敢放出来
前端·gpt·ai编程
前端H7 小时前
微前端 v3 架构升级:从加载隔离到状态协同
前端·架构·状态模式
山河木马7 小时前
GPU自动处理专题3-NDC怎么映射成屏幕像素坐标(视口变换)
javascript·webgl·图形学
陆枫Larry8 小时前
小程序包体积优化:用 SVG 图片替换 iconfont,并保留 CSS 控色能力
前端
Appthing8 小时前
在 TanStack Start 中使用 VitePWA 的正确配置
javascript