diff --git a/chapters.yml b/chapters.yml index c2e4a9f..863e2d0 100644 --- a/chapters.yml +++ b/chapters.yml @@ -2,6 +2,7 @@ - clipboard.md: Clipboard API - fetch.md: Fetch API - fontface.md: FontFace API +- formdata.md: FormData 对象 - geolocation.md: Geolocation API - headers.md: Headers 对象 - intersectionObserver.md: IntersectionObserver diff --git a/docs/formdata.md b/docs/formdata.md index bdfc8bd..c72d6ed 100644 --- a/docs/formdata.md +++ b/docs/formdata.md @@ -20,26 +20,53 @@ const formData = new FormData(form); 上面示例中,`FormData()`的参数`form`就是一个表单的 DOM 节点对象。 -下面是用法示例。 +下面是用法示例,通过脚本发送表单数据。 + +```html +
+ + Picture: + +
+ + +``` + +浏览器向服务器发送表单数据时,不管是用户点击 Submit 按钮发送,还是使用脚本发送,都会自动将其编码,并以`Content-Type: multipart/form-data`的形式发送。 + +`FormData()`还有第三种用法,如果想把“提交”(Submit)按钮也加入表单的键值对,可以把按钮的 DOM 节点当作`FormData()`的第二个参数。 ```javascript -const form = document.querySelector('#subscription'); +new FormData(form, submitter) +``` -try { - let response = await fetch('subscribe.php', { - method: 'POST', - body: new FormData(form), - }); +上面代码中,`submitter`就是提交按钮的 DOM 节点。这种用法适合表单有多个提交按钮,服务端需要通过按钮的值来判断,用户到底选用了哪个按钮。 - const result = await response.json(); +```javascript +// 表单有两个提交按钮 +// +// - console.log(result); -} catch (error) { - console.log(error); -} +const form = document.getElementById("form"); +const submitter = document.querySelector("button[value=save]"); + +const formData = new FormData(form, submitter); ``` -浏览器向服务器发送 FormData 对象时,不管是用户点击 Submit 按钮发送,还是使用脚本发送,都会自动将其编码,并以`Content-Type: multipart/form-data`的形式发送。 +上面示例中,`FormData()`加入了第二个参数,实例对象`formData`就会增加一个键值对,键名为`intent`,键值为`save`。 ## 实例方法 @@ -49,12 +76,57 @@ try { ```javascript FormData.append(name, value) -FormData.append(name, value, file) +FormData.append(name, blob, fileName) ``` -它的第一个参数是键名,第二个参数是键值。 +它的第一个参数是键名,第二个参数是键值。上面的第二种形式`FormData.append(name, blob, fileName)`,相当于添加一个文件选择器``,第二个参数`blob`是文件的二进制内容,第三个参数`fileName`是文件名。 + +如果键名已经存在,它会为其添加新的键值,即同一个键名有多个键值。 -如果键名已经存在,它会为其添加新的键值。 +下面是一个用法示例。 + +```javascript +let formData = new FormData(); +formData.append('key1', 'value1'); +formData.append('key2', 'value2'); + +for(let [name, value] of formData) { + console.log(`${name} = ${value}`); +} +// key1 = value1 +// key2 = value2 +``` + +下面是添加二进制文件的例子。 + +```javascript +// HTML 代码如下 +// + +let imageBlob = await new Promise( + resolve => canvasElem.toBlob(resolve, 'image/png') +); + +let formData = new FormData(); +formData.append('image', imageBlob, 'image.png'); + +let response = await fetch('/article/formdata/post/image-form', { + method: 'POST', + body: formData +}); + +let result = await response.json(); +console.log(result); +``` + +下面是添加 XML 文件的例子。 + +```javascript +const content = 'hey!'; +const blob = new Blob([content], { type: "text/xml" }); + +formData.append('userfile', blob); +``` ### delete() @@ -81,6 +153,19 @@ const values = [...formData.entries()]; console.log(values); ``` +下面是使用`entries()`遍历键值对的例子。 + +```javascript +formData.append("key1", "value1"); +formData.append("key2", "value2"); + +for (const pair of formData.entries()) { + console.log(`${pair[0]}, ${pair[1]}`); +} +// key1, value1 +// key2, value2 +``` + ### get() `get()`用于获取指定键名的键值,它的参数为键名。 @@ -89,11 +174,11 @@ console.log(values); FormData.get(name) ``` -如果该键名有多个键值,只返回第一个键值。 +如果该键名有多个键值,只返回第一个键值。如果找不到指定键名,则返回`null`。 ### getAll() -`getAll()`用于获取指定键名的所有键值,它的参数为键名,返回值为一个数组。 +`getAll()`用于获取指定键名的所有键值,它的参数为键名,返回值为一个数组。如果找不到指定键名,则返回一个空数组。 ```javascript FormData.getAll(name) @@ -115,16 +200,32 @@ FormData.has(name) FormData.keys() ``` +下面是用法示例。 + +```javascript +const formData = new FormData(); +formData.append("key1", "value1"); +formData.append("key2", "value2"); + +for (const key of formData.keys()) { + console.log(key); +} +// key1 +// key2 +``` + ### set() `set()`用于为指定键名设置新的键值。它有两种使用形式。 ```javascript FormData.set(name, value); -FormData.set(name, value, filename); +FormData.set(name, blob, fileName); ``` -它的第一个参数为键名,第二个参数为键值。如果指定键名不存在,它会添加该键名。 +它的第一个参数为键名,第二个参数为键值。上面第二种形式为上传文件,第二个参数`blob`为文件的二进制内容,第三个参数`fileName`为文件名。该方法没有返回值。 + +如果指定键名不存在,它会添加该键名,否则它会丢弃所有现有的键值,确保一个键名只有一个键值。这是它跟`append()`的主要区别。 ### value() @@ -134,3 +235,17 @@ FormData.set(name, value, filename); FormData.values() ``` +下面是用法示例。 + +```javascript +const formData = new FormData(); +formData.append("key1", "value1"); +formData.append("key2", "value2"); + +for (const value of formData.values()) { + console.log(value); +} +// value1 +// value2 +``` +