现代 Web 应用中频繁使用的一项功能就是表单数据序列化,XMLHttpRequest 2 级为此定义了 FormData 类型,FormData 为序列化表单以及创建与表单格式相同的数据(通过 JS 来模拟表单键值对)提供了便利。
使用 post 发送表单键值对格式的请求时,依然可以使用查询字符串格式,只是要放在请求体中,即传入 send() 中,介绍以下几种方法:
方法1: 直接模仿表单提交的形式,缺点是需要手动设置请求头,还要自己序列化为查询字符串的形式传给 xhr 对象。
方法2: 使用 FormData() 构造函数,浏览器会自动识别并添加请求头 "Content-Type: multipart/form-data",且参数依然像是表单提交时的那种键值对儿,此外 FormData() 构造函数 new 时可以直接传入 form 表单的 dom 节点。
方法3: 使用 URLSearchParams() 构造函数传入查询字符串,返回的实例和 FormData 相似,同时浏览器也做出相同的行为。
另外,URLSearchParams() 构造函数 new 时可以直接传入查询字符串格式的参数,比如:
可见 send() 方法很灵活:
第一行是请求行,指明了方法、URI 和 HTTP 版本号;
接着是消息头(简单起见,只有一个 Content-Type);
然后空出一行;
接下来就是消息体,可以看到使用 multipart/form-data 时,消息体通过 boundary 来分隔多个字段,被分隔的每个字段都有自己的小头部和小消息体,且也用空行分隔。如此,提供了额外的信息。
字段的值可能是普通的字符,也可能是二进制文件:
multipart/form-data 最初由 《RFC 1867: Form-based File Upload in HTML》 文档定义。
文档简介中说明文件上传作为一种常见的需求,在目前(1995年)的html中的form表单格式中还不支持,因此发明了一种兼容此需求的MIME type。
文档中也写了为什么要新增一个类型,而不使用旧有的 application/x-www-form-urlencoded :因为旧有类型不适合用于传输大型二进制数据或者包含非ASCII字符的数据。平常我们使用这个类型都是把表单数据使用url编码后传送给后端,二进制文件当然没办法一起编码进去了。所以 multipart/form-data 就诞生了,专门用于有效的传输文件。
参考:
1. 豆瓣:JavaScript高级程序设计(第3版)
2. MDN: FormData
3. MDN: XMLHttpRequest.send()
4. 为什么上传文件要使用multipart/form-data
5. 谈谈form-data请求格式
我们先看一个小例子:
html代码:
需求:是获取form表单中的用户名和密码并包装成一个对象
这个需求是我们大部分时候在发送ajax请求时需要做的一个工作。
传统JS写法:
看一下效果:
可以看到,我们已经实现了需求,但是我们写的JS代码很繁琐,我们需要先获取form表单中input框元素,然后元素的value值,最后包装成一个对象。
FormData的JS写法:
效果如下:
通过这个例子你应该能感受到FormData的便利性,只需要 new FormData(form) 一句代码就可以把form表单内的所有信息都以键值对的形式包装成一个对象返回。
FormData对象是用来将form表单数据编译成键值对,这么做有两个好处:
FormData的常用 *** 作方法:
FormData对象可以帮我们更方便的收集表单数据并中的整理成对象,大大方便了我们发送ajax请求。
1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
2.异步上传二进制文件
1.准备HTML表单,表单中需要提交数据的表单控件必须添加name属性
2.将HTML表单转化为FormData对象,通过
3.提交表单对象
具体 *** 作
①获取到提交表单的按钮并且给按钮添加点击事件,一旦点击就发送请求
②生成formData实例,将获取到的表单元素作为参数
③创建Ajax对象
④配置请求的方式以及地址
⑤将表单实例作为请求参数发送出去
⑥监听onload事件,当响应状态码为200时,说明请求成功,将结果打印出来即可
①formData. get ( 'key' )------用来获取表单对象的属性值,也就是输入框输入的值,key是表单的name所对应的名字
②formData. set ( 'key' ,'value')------用来设置表单对象属性的值,如果设置的表单属性存在就会覆盖原有的值,如果不存在就会创建这个属性
③formData. delete ( 'key' )-------删除表单对象的属性值
④formData. append ( 'key' ,'value')------向表单对象中添加值,如果属性已存在,那么会保留新旧两个属性及值,但是打印的话,后面添加的会覆盖前面的
①upload事件在上传文件的过程中持续触发,它又有一个onprogress方法
②已经上传的文件大小/文件的总大小*100+'%'-------->loaded (已经上传的文件大小)/ total (文件总大小)*100+'%'
③设置一个变量用来接收进度条的值,之后将值赋值给HYML样式即可
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)