发表于: 2017-06-12 23:33:21
1 1082
今天完成的事情:
学习了angular表单上传的相关知识:
通常,我们使用 HTML 的标签 <form> 来为用户输入创建一个表单,使用 <input type="file"> 作为文件上传的控件。
要将表单的数据发送给后台,不仅要通过指定 <form> 的属性 method 来确定发送数据的 HTTP 方法而且需要通过指定 <form> 的属性 enctype 来确定对发送数据的编码方式。
表单 form 的属性 method
<form> 的属性 method 规定用于发送 form-data 的 HTTP 方法,其值可以为 get 或者 post。get 请求会将表单的数据编码后以 name1=value1&name2=value2 的形式附加到请求的 url 后面进行发送。post 请求会将表单的数据进行编码之后置于请求体中进行发送。
<form> 标签的属性 entype 用来规定在发送表单数据之前应该如何对其进行编码,其实就是用来指定请求的编码类型。
enctype属性有 3 个取值,在 w3school 中对于其取值的描述如下:
application/x-www-form-urlencoded 空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值
multipart/form-data 不对字符编码。在使用包含文件上传控件的表单时,必须使用该值
text/plain 空格转换为 "+" 加号,但不对特殊字符编码
其中 application/x-www-form-urlencoded 是默认采用的编码的方式,如果表单 <form> 中有用到文件上传的控件,就要手动指定编码为 multipart/form-data。
下面分别对上述这几种编码方式进行举例(均基于 post 请求方式)
编码为 application/x-www-form-urlencoded 的情况
首先,构造一个表单:
<form method="post" action="/" enctype="application/x-www-form-urlencoded">
<input type="text" name="name1" placeholder="name1">
<input type="text" name="name2" placeholder="name2">
<input type="submit">
</form>
在输入框内分别输入 i'm name1 和 name@2 ,根据编码规则,提交表单的时候,表单数据会被编码成 name1=i%27m+name1&name2=name%402 置于请求体中进行传递,在 chrome 浏览器中执行结果也正如预期所示。
编码为 multipart/form-data 的情况
编码为 multipart/form-data 的情况又有所不同,先来看看示例代码的结果。
示例代码:
<form method="post" action="/" enctype="multipart/form-data">
<input type="text" name="name1" placeholder="name1">
<input type="text" name="name2" placeholder="name2">
<input type="file" name="inputfile">
<input type="submit">
</form>
在输入框内分别输入 i'm name1 和 name@2 ,再选择一个名为 testfile.txt 的文件上传,可以在 chrome 中看到发送的请求如下:
注意图片中的红框部分,Content-Type 值为 multipart/form-data; boundary=----WebKitFormBoundaryBdpfgMg4VKAZat6C ,其中多了一个叫做 boundary 的字段,它是由浏览器随机生成的一个字符串,作为表单数据的分割边界来使用的,在服务器端会根据这个 boundary 边界字段来解析表单数据。
可以明显看到,以边界分割的每一段均对应于一项表单数据,每项数据均包含有一个 Content-Disposition 字段和一个 name 字段,而对于上传的文件则会多一个指定上传文件名字的 filename 的属性和上传文件的类型的 Content-Type 字段,由于例子中上传的文件是 .txt 格式的文件,因此 Content-Type 的值为 text/plain,有关文件的扩展名和 Content-Type 的对照表可以看这里。
编码为 text/plain 的情况
这种情况与编码为 application/x-www-form-urlencoded 的情况类似,唯一的差别就在于 text/plain 不对特殊字符进行编码。
文件上传的 Angular 实现
基于 FormData 的实现
实现的思路:通过 File API 获取控件中上传的文件,利用 FormData 类型构造表单数据上传。
基本知识:File API 和 FormData 类型
File API
File API(文件API)为Web 开发人员提供一种安全的方式来访问用户计算机中的文件,并更好地对这些文件执行操作。
具体来讲,File API 在表单中的文件输入字段的基础上,又添加了一些直接访问文件信息的接口。HTML5 在 DOM 中为文件输入元素添加了一个 files 集合。在通过文件输入字段选择了一或多个文件时,files 集合中将包含一组 File 对象,每个 File 对象对应着一个文件。
构造一个文件上传的表单,通过如下 jQuery 代码:
$("input[type='file']")[0].files
在 chrome 浏览器控制台中可以看到获得的信息如下:
可以看到选取的文件 testfile.txt 的相关信息,因此可以通过上述方式来获得上传的文件。
关于 File API 的更多叙述可以在这里获得。
FormData 类型
FormData 是在 XMLHttpRequest Level 2 中定义的,为序列化表单以及创建与表单格式相同的数据(用于通过XHR 传输)提供了便利。
下面这段对于 FormData 对象的描述引用自 MDN,更多关于 FormData 类型的叙述可以在这里获得。
XMLHttpRequest Level 2 添加了一个新的接口 FormData. 利用FormData 对象,我们可以通过 JavaScript 用一些键值对来模拟一系列表单控件,我们还可以使用 XMLHttpRequest 的 send() 方法来异步的提交这个"表单". 比起普通的 ajax, 使用 FormData 的最大优点就是我们可以异步上传一个二进制文件.
可见,我们可以使用 FormData 对象来模拟实现文件上传时候提交的表单数据,而构造提交的数据是通过 FormData 的方法 append() 实现的,它用于给当前 FormData 对象添加一个键/值对。
2.学习进度条的实现,目前还没弄的太清楚,明天应该能完成。
明天计划的事情:
继续任务9
遇到的问题:
暂无
收获:
angular上传文件的基础知识
评论