[FE] 用 FormData 上传多个文件到 MultipartFile[] 接口

如题所述

第1个回答  2022-06-12

最近有一个场景,在提交表单的时候,需要实现添加附件的功能,
表单内容要先提交到服务端,创建一个 issue,然后再将附件添加到这个 issue 中。

所以,附件在用户添加的时候,是 没有立即上传 的,
用户可以随意在浏览器端添加和删除,issue 创建后再一起上传。

前端采用的组件库是 antd ,用到了 upload 组件。
服务端接口是自定义实现的,也许并不支持 antd upload 上传组件的规范。

服务端接受数据时,使用了 MultipartFile ,这是 Spring 框架中常用的 写法 。

我们先看看 html input[type=file] 组件默认行为,

点击 “选择文件”,浏览器会弹出一个窗口,

选中一个文件,点 “打开”,就会触发 onchange 事件,

在 onchange 事件中,可以通过 e.target.files[0] 拿到刚才上传的那个 File 对象

再来看一下 upload 组件的默认行为,

点击 “添加”,浏览器也会弹出那个选择文件的窗口,

选中一个文件,点 “打开”,发现上传失败了。

打开控制台,看到 upload 组件向 / 这个地址发送了一个 POST 请求,

数据格式如下,

我们可以向 upload 组件传入 action 参数,修改 POST 请求地址,

但是,选中文件后立即上传 不符合 我们的场景,我们需要提交表单之后,将多个文件统一上传。
所以我们得自定义 upload 组件的行为。

upload 组件的有一个 customRequest 属性( #api ),
它可以配置自定义的上传行为。

我们的思路是,先将选中后自动上传的行为取消掉,然后再在提交表单后统一上传。
取消自动上传 的实现片段如下,

我们只需要在 customRequest 回调中,调用它的 onSuccess 参数即可。

删除也是可以用的,

现在我们添加两个附件,

接着来看前端怎样将这些附件,统一上传给服务端,具体实现如下,

可以看到请求成功了(项目中的 url 跟本例稍有不同,下图只为了示意),

还有几个需要注意的点:

上文 httpClient.post 实际调用了 XMLHttpRequest 发送请求,可能会遇到 跨域 的问题。
所以在调试上传接口的时候,需要检查一下服务端的配置,是否支持跨域请求。

CORS 相关的内容大致如下:

在预检请求阶段,服务端对 OPTIONS 请求的响应头中会包含 Access-Control-Allow-Origin ,

表明服务端接受该域 http://foo.example 的跨域请求。

注:
这里需要后端实现 OPTIONS 方法,后端框架一般会通过配置方式统一处理(返回 200 或 204,不能是 4xx)。
如果未配置统一处理方式,框架可能会直接返回 404 导致预检请求失败,CORS 请求也会失败。

使用 XMLHttpRequest 发送请求时,也可以携带 cookie 信息,

同时 预检请求中服务端响应头,也要包含 Access-Control-Allow-Credentials ,否则就不会发送 cookie

对于附带 cookie 的请求,服务器不能设置 Access-Control-Allow-Origin 的值为 “ * ”,否则请求将会失败。
而将 Access-Control-Allow-Origin 的值设置为具体的地址 http://foo.example ,请求才能成功。

我们上传功能用到了携带 cookie 的跨域请求,
可以看到服务端响应头中确实包含了, Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 两个字段。

Spring: Uploading Files
Spring: org.springframework.web.multipart #MultipartFile

ant-design v4.11.1
Ant Design - Upload #API

MDN: CORS

[FE] 用 FormData 上传多个文件到 MultipartFile[] 接口
服务端接受数据时,使用了 MultipartFile ,这是 Spring 框架中常用的 写法 。我们先看看 html input[type=file] 组件默认行为,点击 “选择文件”,浏览器会弹出一个窗口,选中一个文件,点 “打开”,就会触发 onchange 事件,在 onchange 事件中,可以通过 e.target.files[0] 拿到刚才...

form-data上传多文件,java后端怎么接收?
在FileUploadController中,通过MultipartFile对象接收多个文件上传请求,并使用阿里云OSS客户端将文件上传至指定路径。上传完成后,将文件的URL存储到数据库中,以供后续使用。通常使用JPA或MyBatis等框架操作数据库,创建相应的实体类和存储库。具体实现时,需要考虑异常处理、文件大小限制、文件类型限制、权限验...

使用MultipartFile上传文件
MultipartFile的两个主要实现类使得文件上传更加灵活和高效。为了在项目中使用它,需要加入对应的依赖。在前端上传文件时,必须使用multipart\/form-data格式发送数据,否则后台将无法接收到数据。具体实现如下:对于使用form表单上传文件,需在form标签中添加属性enctype="multipart\/form-data"。上传多个文件时,需...

一文教你实现java中的文件上传下载
3. 前端实现: - 前端HTML提供File组件,如拖拽或点击选择文件上传。 - 使用JavaScript的drop事件处理文件拖拽。 - AJAX通过FormData上传文件,如`formData.append('file', file);`4. 后端接口:在Spring Boot中,通过`@RequestParam`接收上传的文件,如`MultipartFile file`。5. 持久化与审计...

springboot多文件上传
在接口方法中,通过`MultipartFile[] files`接收前端上传的多个文件。遍历该数组,对每个文件进行处理。处理包括保存文件到服务器文件系统或存储到数据库等操作。四、保存文件 对于每个上传的文件,可以使用Spring的`FileStorageService`服务来保存文件。服务中需要实现文件的存储逻辑,如生成唯一文件名、确定存储...

springboot上传文件到本地?
上传的基本原理就是前端根据文件大小,按块大小分成很多块,然后多线程同时上传多个块,同时调用服务端的上传接口,服务端会生成很多小块小块的文件。 所有块都上传完之后,前端再调用一个服务端的merge接口,服务端把前面收到的所有块文件按顺序组合成最终的文件。 springboot多文件上传 MultipartFile提供了以下方法来获取上...

java怎么上传大文件
前端采用Dropzone插件实现多文件拖拽上传,后端则使用MultipartFile接口处理文件接收。Dropzone支持拖拽上传功能,方便用户上传多个文件。在处理大文件时,直接使用getBytes方法会一次性加载所有数据到内存中,可能导致内存溢出。因此,解决方法是通过流的方式逐步读取文件数据,并分批处理,避免一次性加载全部文件内容。

upload文件上传快速入门
@PostMapping("upload")`接收POST请求,处理`MultipartFile`。确保文件不为空,并尝试将其保存到指定路径,如果发生异常,返回相应错误信息。前端通过JavaScript的`FormData`对象,将文件发送到`\/file\/upload`接口。使用axios库发起POST请求,将文件添加到表单数据中,并在上传成功后更新前端显示的文件路径。

springboot上传图片到服务器?
isEmpty,文件上传内容为空,或者根本就没有文件上传;getSize,文件上传的大小。transferTo(Filedest),保存文件到目标文件系统;同时上传多个文件,则使用MultipartFile数组类来接受多个文件上传:\/\/多文件上传@RequestMapping(value="\/batch\/upload",method=RequestMethod.POST)??@ResponseBody??publicString...

springboot上传文件到本地?
上传的基本原理就是前端根据文件大小,按块大小分成很多块,然后多线程同时上传多个块,同时调用服务端的上传接口,服务端会生成很多小块小块的文件。 所有块都上传完之后,前端再调用一个服务端的merge接口,服务端把前面收到的所有块文件按顺序组合成最终的文件。 springboot多文件上传 MultipartFile提供了以下方法来获取上...

相似回答
大家正在搜