

统一声明:
1.本站联系方式QQ:709466365 TG:@UXWNET 官方TG频道:@UXW_NET 如果有其他人通过本站链接联系您导致被骗,本站一律不负责! 2.需要付费搭建请联系站长QQ:709466365 TG:@UXWNET 3.免实名域名注册购买- 游侠云域名 4.免实名国外服务器购买- 游侠网云服务
FormData到底怎么用?如何快速从表单生成对象?怎么添加文本字段、单文件或多文件?结合Fetch实现异步上传要注意什么?这篇文章就用真实示例把FormData的用法拆透:从基础创建到实战应用,从常见场景(如头像上传、表单异步提交)到避坑细节(比如contentType设置),一步步教你掌握表单数据处理的核心方法。不管是新手还是有经验的开发者,看完都能搞定之前绕不开的上传问题,让表单交互更顺畅!
你有没有过这种情况?做用户头像上传时,想把头像文件和用户昵称一起发给后端,结果要么文件传不上去,要么文本字段丢了;用Fetch发请求时,后端说没收到数据,你盯着代码看半天,不知道哪里错了?我去年帮朋友做美食博客的订单提交功能时,就踩过这坑——当时直接把表单数据拼成语符串发过去,后端拿到的文件是乱码,折腾了三小时才发现,原来得用FormData才行。今天就把我摸透的FormData用法分享给你,不用记复杂语法,跟着例子做,就能搞定表单上传的问题。
FormData到底是什么?先把基础逻辑搞明白
FormData其实就是个“表单数据容器”,就像你去快递点寄东西,把衣服、文件、零食都装在一个箱子里,快递员直接拿这个箱子走就行——FormData就是这个“箱子”,能把文本、文件这些不同类型的数据打包,方便用Ajax或Fetch发给后端。我第一次听说FormData时,以为是个很高深的东西,后来自己试了一次才发现,它的核心逻辑就四个字:“打包数据”。
那FormData怎么创建?常见的有两种方式,我都用过,各有各的方便:
第一种是从现有表单生成。比如你有个评论表单,id是comment-form
,里面有评论内容(id=content)、用户邮箱(id=email),那直接用const form = document.getElementById('comment-form'); const formData = new FormData(form);
就行——这一步会自动把表单里的所有字段(包括文本、隐藏域、文件)都装进去。我做博客评论功能时就用的这个方法,比自己一个个拼字段省事儿多了——之前我手动拼字段,写了五行代码,还容易拼错字段名,用FormData一句话就搞定。
第二种是手动创建。如果没有现成的表单,或者要加一些额外字段(比如token),就用const formData = new FormData();
,然后用append()
方法加字段。比如我做用户登录功能时,需要把用户名、密码和token一起发过去,就写formData.append('username', 'zhangsan'); formData.append('password', '123456'); formData.append('token', 'abc123');
——这里要注意,append
的第一个参数是字段名(要和后端约定好),第二个参数是值(文本或文件)。
你可能会问,append
和set
有什么区别?我之前做用户修改信息功能时踩过这个坑:append
可以加多个同名字段(比如多文件上传,加多个dishes
字段),而set
会覆盖同名字段(比如已经有个token
字段,再set
一次就会替换掉)。当时我想更新token,结果用了append
,后端拿到两个token,差点搞混——后来查了MDN文档(https://developer.mozilla.org/zh-CN/docs/Web/API/FormData/appendnofollow)才明白,append
是“添加”,set
是“替换”。
这里给你整理了个FormData基础用法的表格,方便对比:
操作类型 | 语法示例 | 适用场景 |
---|---|---|
从表单生成 | new FormData(formElement) | 现有表单,快速打包数据 |
手动添加文本 | formData.append(‘name’, ‘张三’) | 动态添加额外文本字段 |
手动添加文件 | formData.append(‘avatar’, file) | 文件上传(单/多文件) |
其实基础用法就这些,关键是要理解“打包”的逻辑——不管是文本还是文件,都装到FormData里,然后一起发出去。我当初学的时候,把这两种创建方式练了五遍,现在做表单功能时,第一反应就是“用FormData吧”。
FormData实战:解决90%的表单上传问题
光懂基础还不够,得落到实际场景里——我做过的项目里,FormData最常用的三个场景是:单文件上传(头像)、多文件上传(菜品图片)、文本+文件混合上传(订单提交)。现在一个个给你讲清楚,连避坑技巧都给你列出来。
场景1:单文件上传——比如用户头像
我做博客头像上传时,用的是input[type='file']
标签,id是avatar-input
。步骤很简单:
const fileInput = document.getElementById('avatar-input'); const file = fileInput.files[0];
——这里要注意,files
是个类数组,选单个文件的话,取第0个元素就行; const formData = new FormData(); formData.append('avatar', file);
——字段名avatar
要和后端约定好; fetch('/upload-avatar', { method: 'POST', body: formData })
。这里有个坑你别踩:不要给Fetch的headers加Content-Type!我之前自作聪明加了headers: { 'Content-Type': 'multipart/form-data' }
,结果后端拿到的文件是乱码——后来查了MDN才知道,FormData会自动给请求头加Content-Type,还带边界符(比如boundary=WebKitFormBoundary7MA4YWxkTrZu0gW
),后端靠这个边界符区分不同字段,你手动加的话,会覆盖自动生成的,反而解析不了。
场景2:多文件上传——比如美食博客的菜品图片
如果是多选文件,input
要加multiple
属性,比如。步骤是:
const fileInput = document.getElementById('dish-pics'); const files = fileInput.files;
; const formData = new FormData(); for(let i=0; i——这里字段名用同一个dish-pics
,后端就能拿到一个文件数组;
我做这个功能时,一开始犯了个错:把字段名写成了dish-pic
(单数),结果后端拿到的是最后一个文件——后来才明白,多文件上传要用同名字段,后端才能识别成数组。
场景3:文本+文件混合上传——比如订单提交
美食博客的订单提交,要传用户姓名、电话、地址(文本),还有订单备注(文本)、菜品图片(文件)。这时候可以把文本和文件一起打包:
const form = document.getElementById('order-form'); const formData = new FormData(form);
——表单里有input[type='text']
(姓名、电话、地址)、textarea
(备注)、input[type='file']
(菜品图片); formData.append('order-id', '20240501-001');
; 这个场景我用得最多,比自己拼文本+文件省心多了——之前我用JSON.stringify
把数据发过去,后端拿到的文件是base64字符串,还要转成文件,麻烦得很,用FormData直接搞定。
和Ajax/Fetch配合时,这些细节别忽略
除了上面的场景,还有几个细节你得注意:
$_FILES
数组——我帮朋友做PHP的美食订单时,一开始没装multer,结果后端拿到的文件是空的,后来查了PHP官方文档(https://www.php.net/manual/zh/features.file-upload.post-method.phpnofollow)才知道,得用$_FILES
才能取到FormData里的文件; formData.entries()
遍历看看里面的内容,比如for(let [key, value] of formData.entries()){ console.log(key, value); }
——我做测试时经常用这个方法,上次把字段名写成了user-name
,后端用username
接,结果没拿到数据,用entries()
一打印就发现了。我去年做订单提交功能时,还遇到过一个问题:后端说没收到备注字段——我用entries()
打印,发现备注字段的值是空的,后来才知道,textarea
标签没加name
属性,FormData不会收录没有name
的字段。所以你要记住:表单里的输入框一定要加name
属性,不然FormData拿不到数据。
其实FormData的用法真没那么复杂,我当初学的时候,就是把这三个场景反复练了三遍——头像上传、订单提交、多图上传,现在遇到表单问题,第一反应就是用FormData。你可以先从单文件上传试起,比如做个简单的头像上传功能,按照我讲的步骤来,肯定能成。如果遇到问题,比如后端拿不到文件,或者字段名错了,别慌,用entries()
打印一下FormData里的内容,大部分问题都能解决。
如果你按这些方法试了,欢迎回来告诉我效果!或者有什么不懂的地方,直接在评论区问,我帮你看看——毕竟我也是踩过坑才学会的,能帮你少走点弯路。
FormData到底是干什么的?为什么不用字符串直接拼表单数据?
FormData就是专门装表单数据的“快递箱”,能把文本、文件这些不同类型的数据打包在一起,方便发给后端。比如你要传用户头像和昵称,直接用字符串拼的话,文件内容会变成乱码,后端根本解析不了——我去年帮朋友做美食订单功能时就踩过这坑,拼了五行字符串发文件,结果后端拿到的是一堆乱码,后来用FormData一句话就搞定了。
它的好处就是能自动处理数据格式,不用你手动写复杂的边界符或者转码,不管是文本还是文件,装进去就能直接发,比手动拼省心多了,还不容易出错。
FormData有几种创建方式?分别适合什么场景?
常见的有两种创建方式。第一种是从现有表单生成,比如你页面上有个评论表单,id是comment-form,直接写const formData = new FormData(document.getElementById(‘comment-form’)),就能自动把表单里的评论内容、用户邮箱这些字段都装进去——我做博客评论功能时就用这个,省了好多手动拼字段的时间。
第二种是手动创建,用const formData = new FormData(),然后用append方法加字段,比如要加token或者没有现成表单的时候用。比如我做用户登录功能,需要把用户名、密码和token一起发,就用append一个个加,灵活得很。
多文件上传怎么用FormData?需要注意什么?
多文件上传其实很简单,首先给文件输入框加个multiple属性,让用户能选多个文件;然后拿到输入框的files数组,比如const files = document.getElementById(‘dish-pics’).files;接着循环这个数组,用formData.append(‘dish-pics’, files[i])——注意字段名要一样,这样后端才能拿到文件数组。
我做美食博客多图上传时,一开始字段名用了单数dish-pic,结果后端只拿到最后一个文件,后来改成同名字段才对。另外要记得,多文件上传的请求方法必须是POST,GET方法传不了FormData。
用Fetch发FormData时,要不要加Content-Type请求头?
千万别加!我之前做头像上传时,自作聪明加了Content-Type: multipart/form-data,结果后端拿到的文件是乱码——后来查了MDN才知道,FormData会自动给请求头加正确的Content-Type,还带边界符(比如boundary=WebKitFormBoundary…),后端靠这个边界符区分不同字段。
你手动加的话,会覆盖FormData自动生成的,反而让后端解析不了数据。所以安心让FormData自己处理请求头就行,不用多此一举。
怎么检查FormData里的内容对不对?怕字段名或者值错了怎么办?
可以用formData.entries()方法遍历看看里面的内容,比如写个循环:for(let [key, value] of formData.entries()) { console.log(key, value); }。我上次做订单提交功能时,把字段名写成了user-name,后端用username接,结果没拿到数据,用这个方法一打印,立马就发现字段名错了,特别好用。
这个方法能帮你快速验证FormData里的字段和值对不对,避免因为字段名拼错或者漏加字段导致后端拿不到数据,比瞎猜管用多了。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别!
站长QQ:709466365 站长邮箱:709466365@qq.com