本文最后更新于:2023年1月12日 下午
前言
在做项目时,有一个接口要求上传文件的同时能携带其它数据,在这里使用的是FormData
对象来进行操作。简单介绍一下这个对象。
FormData
接口提供了一种表示表单数据的键值对 key/value
的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send()
方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data"
,它会使用和表单一样的格式。(以上出自这里)
单文件上传
这里使用FormData
的append()
方法,该方法会向FormData
对象中添加新的属性值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| <input id='file' type='file'/> <button id='upload'>上传</button> <script> const input = document.getElementById('file'); const uploadBtn = document.getElementById('upload'); let files = null;
input.onchange = (e) => { const file = input.files[0]; files = file; }
const uploadFile = (file) => { const formData = new FormData(); formData.append('file', file); fetch('https://xxx.com', { method: 'POST', body: formData }) .then(res => { }) .catch(err => { }) } uploadBtn.onclick = () => { if (!files) { alert('请选择文件') return } uploadFile(files); } </script>
|
注:上传文件是不需要我们自己设置Content-Type
头的,设置了反而无法上传,切记,切记,切记!!!
详细的可以查看这个issue: https://github.com/github/fetch/issues/505#issuecomment-293064470
多文件上传
如果FormData
的属性值中已经存在对应的属性值也不会被覆盖,而是会将这个新值添加到已有集合的后面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| + <input id='file' type='file' multiple/> <button id='upload'>上传</button> <script> const input = document.getElementById('file'); const uploadBtn = document.getElementById('upload'); let files = null;
input.onchange = (e) => { - const file = input.files[0]; - files = file; + const files = input.files + files = files; }
- const uploadFile = (file) => { + const uploadFile = (files) => { const formData = new FormData(); - formData.append('file', file);
+ for (const file of files) { + formData.append('files', file); + } fetch('https://xxx.com', { method: 'POST', body: formData }) .then(res => { }) .catch(err => { }) } uploadBtn.onclick = () => { if (!files) { alert('请选择文件') return } uploadFile(files); } </script>
|
多文件上传并携带其他数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <input id='file' type='file' multiple/> <button id='upload'>上传</button> <script> const input = document.getElementById('file'); const uploadBtn = document.getElementById('upload'); let files = null;
input.onchange = (e) => { const files = input.files files = files; }
- const uploadFile = (files) => { + const uploadFile = (files, payload) => { const formData = new FormData(); for (const file of files) { formData.append('files', file); } + for (const key in payload) { + formData.append([key], payload[key]); + } fetch('https://xxx.com', { method: 'POST', body: formData }) .then(res => { }) .catch(err => { }) } uploadBtn.onclick = () => { if (!files) { alert('请选择文件') return } - uploadFile(files); + uploadFile(files, {id: 'upload'}); } </script>
|
FormData
对象的set()
方法和append()
方法比较,set()
方法指定的键如果存在,会使用新值覆盖原来的值,而append()
方法会把新值添加到已有值集合的后面
参考
[1] https://developer.mozilla.org/zh-CN/docs/Web/API/FormData