FormData可以做些什么事,除了文件上传当然还有文件分片上传呀

简介: FormData 是一个用于表单数据的键值对,可以通过 FormData 对象来模拟表单提交,也可以通过 FormData 对象来实现文件上传。

FormData是一个用于表单数据的键值对,可以通过FormData对象来模拟表单提交,也可以通过FormData对象来实现文件上传。

1. 简单认识

FormData提供了一种表示表单数据的键值对构造方式,可以轻松的将数据通过XMLHttpRequest.send()
方法发送到服务器,如果送出时的编码类型被设为 multipart/form-data,它会使用和表单一样的格式。

最常见的使用场景就是文件上传,但是FormData还可以使用到其他的场景,比如模拟表单提交。

2. 使用

2.1 构造函数

FormData是一个构造函数,它可以接受一个可选的参数,但是在现代浏览器中,它只接受一个HTMLFormElement
对象,如果传入其他类型的参数,会抛出一个TypeError错误。

const formData = new FormData();

or


<form id="form">
    <input type="text" name="name" value="张三">
    <input type="text" name="age" value="18">
</form>

<script>
    const form = document.getElementById('form');
    const formData = new FormData(form);
</script>

注意:表单项的name属性是必须的,否则FormData对象中不会包含该表单项。

2.2 方法

方法 描述
append() 添加一个键值对到FormData对象中
delete() 删除一个键值对
get() 获取一个键值对的值
getAll() 获取一个键值对的所有值
has() 判断FormData对象中是否包含某个键值对
set() 设置一个键值对的值
keys() 返回一个包含所有键名的迭代器
values() 返回一个包含所有键值的迭代器
entries() 返回一个包含所有键值对的迭代器

FormData可以直接使用for...of循环来遍历,也可以使用forEach()方法来遍历。

const formData = new FormData();
formData.append('name', '张三');
formData.append('age', 18);

for (const [key, value] of formData) {
   
    console.log(key, value);
}

formData.forEach((value, key) => {
   
    console.log(key, value);
});

FormData对象中的键值对是有序的,也就是说,键值对的顺序和添加的顺序是一致的。

同时,FormData对象中的键名是不允许重复的,如果重复添加(append)同一个键名,那么会存在两个同名的键值对。

FormData不可以直接打印,如果直接打印,会打印出一个空对象,如果想要打印出键值对,可以使用for...of循环或者forEach()
方法,打印单个值可以使用get方法。

FormData其实还是很简单的,上面的提供的方法也很简单,直接就见名知意了,所以就不过多的介绍了,下面就来看看它的使用场景。

3. 使用场景

使用场景最常用的就是文件上传了,下面就来看看如何使用FormData来实现文件上传。

3.1 文件上传


<form id="form">
    <input type="file" name="file">
    <button type="submit">提交</button>
</form>

<script>
    const form = document.getElementById('form');
    form.addEventListener('submit', (e) => {
    
        e.preventDefault();
        const formData = new FormData(form);

        const xhr = new XMLHttpRequest();
        xhr.setRequestHeader('Content-Type', 'multipart/form-data');
        xhr.open('POST', '/upload');
        xhr.send(formData);
    });
</script>

上面的代码中,我们使用FormData来构造一个formData对象,然后使用XMLHttpRequest对象来发送请求,这样就可以实现文件上传了。

3.2 表单数据序列化


<form id="form">
    <input type="text" name="name" value="张三">
    <input type="text" name="age" value="18">
    <button type="submit">提交</button>
</form>

<script>
    const form = document.getElementById('form');
    form.addEventListener('submit', (e) => {
    
        e.preventDefault();
        const formData = new FormData(form);
        const params = new URLSearchParams(formData);
        console.log(params.toString());
    });
</script>

以前我们使用jQuery来实现表单数据序列化的时候,需要使用serialize()方法,但是现在我们可以直接使用FormData
对象来实现表单数据序列化了。

URLSearchParamsURL的一个属性,可以用来序列化URL的查询字符串,也可以用来序列化FormData
对象,使用UrlSearchParams.toString()可以将URLSearchParams对象序列化为一个查询字符串,这里不一定非要用FormData

3.3 模拟表单提交

const formData = new FormData();
formData.append('name', '张三');
formData.append('age', 18);

const xhr = new XMLHttpRequest();
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.open('POST', '/submit');
xhr.send(formData);

模拟表单提交一般都是浏览器默认完成的,但是有时候我们需要自己来实现,这时候就可以使用FormData对象来实现了。

4. 文件分片上传

开始上大招了,上面的就是为了凑字数的,下面我们来看看如何使用FormData来实现文件分片上传。

4.1 文件分片上传的原理

文件分片上传的原理就是将一个文件分成多个小文件,然后分别上传,这样就可以实现大文件的上传了。

4.2 文件分片上传的实现

const file = document.getElementById('file').files[0];
const chunkSize = 1024 * 1024 * 2; // 2M
const chunkCount = Math.ceil(file.size / chunkSize);

for (let i = 0; i < chunkCount; i++) {
   
    const chunk = file.slice(i * chunkSize, (i + 1) * chunkSize);
    xhrFileUpload(chunk, i);
}

function xhrFileUpload(chunk, index) {
   
    const formData = new FormData();
    formData.append('file', chunk);
    formData.append('index', index);

    const xhr = new XMLHttpRequest();
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
    xhr.open('POST', '/upload');
    xhr.send(formData);
}

上面的代码中,我们使用file.slice()方法来将文件分片,然后使用FormData对象来构造一个formData对象,最后使用XMLHttpRequest对象来发送请求,这样就可以实现文件分片上传了。

当然上面还有一个问题,就是文件分片上传的时候,这里是分为2M一个分片,如果文件太大,那么分片的数量就会很多,这样就会导致请求的数量很多,这样就会导致服务器压力很大,这里是一个优化空间,提示可以使用Web Worker来实现。

5. 总结

FormData对象是一个非常强大的对象,它可以用来构造表单数据,也可以用来模拟表单提交,还可以用来实现文件分片上传,这里只是简单的介绍了一下,更多的内容可以参考MDN

目录
相关文章
|
存储 Linux 索引
【Linux】—— 详解软硬链接
【Linux】—— 详解软硬链接
793 0
|
NoSQL 数据可视化 MongoDB
Windows MongoDB的安装及配置图文说明(非常详细)
Windows MongoDB的安装及配置图文说明(非常详细)
1725 0
|
10月前
|
前端开发 JavaScript NoSQL
如何开发一套绩效管理(KPI)系统?(附架构图+流程图+代码参考)
本文介绍了如何构建科学有效的绩效管理(KPI)系统,帮助企业提升组织效率与员工成长。内容涵盖系统架构设计、功能模块开发、业务流程落地及实操技巧,提供架构图、流程图和核心代码参考,助力快速实现企业绩效管理数字化。
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
人工智能 Serverless 开发者
最佳实践 | 轻松部署,即刻触达 Qwen2.5 的飞一般的体验
通过阿里云函数计算(FC)部署Ollama和Open WebUI,实现Qwen2.5模型的托管与交互。
|
人工智能 程序员 测试技术
通义灵码 AI 程序员核心功能体验
阿里云通义灵码AI程序员已全面上线,成为全球首个同时支持 VS Code、JetBrains IDEs 开发工具的AI程序员产品。
1796 1
通义灵码 AI 程序员核心功能体验
|
iOS开发 开发者 Windows
uniapp云打包ios应用证书的获取方法,生成指南
打包用到的一共两个文件,一个是p12格式的私钥证书,一个是证书profile文件。其中生成p12证书的时候,按照官网的教程,是需要MAC电脑来协助做的,主要是生成一些csr文件和导出p12证书等。其实这些步骤也可以借助一些其他的工具来实现,不一定使用mac电脑,用windows电脑也可以创建。
1578 0
|
小程序 开发者 UED
支付宝小程序UI/UX设计原则与最佳实践
支付宝小程序UI/UX设计原则与最佳实践
940 6
|
消息中间件 存储 微服务
RPC 和消息队列的区别
RPC 和消息队列的区别
776 0
|
JavaScript
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
vue中使用echarts绘制双Y轴图表时,刻度没有对齐的两种解决方法
4713 0