表单提交与后端接收
HTML中的表单有几个重要的属性,分别是action、method、enctype
- action:用于设定表单提交的服务器的 URL,可以是相对路径和绝对路径。
- method:用于设定 HTTP 请求的方式。
- enctype:用于定义表单数据提交到服务器的过程中如何对数据进行编码
本次主要针对enctype进行测试实验。method统一使用POST方式。
后端使用SpringBoot2.x,Spring在参数处理方面已经做了很好的处理了。
SpringBoot上传文件的一些基本设置
#是否开启文件上传支持,默认是truespring.servlet.multipart.enabled=truespring.servlet.multipart.max-request-size=100MBspring.servlet.multipart.max-file-size=10MB#文件写入磁盘的阈值,默认是0,这意味着文件将立即写入磁盘spring.servlet.multipart.file-size-threshold=0
application/x-www-form-urlencoded方式
默认方式是第一种 application/x-www-form-urlencoded,当使用 form 表单提交数据时,会对数据进行编码。
前端代码:
<form id="form" action="http://localhost:8080/form/test" method="POST" enctype="application/x-www-form-urlencoded">name<input type="text" name="name" id="name">age<input type="text" name="age" id="age">submit<input type="submit"></form>
后端接收方式
// 实体类@Datapublic class Person{private String name;private Integer age;}// 控制器@CrossOrigin("*")@RestController@RequestMapping("/form")public class FormController{@PostMapping("/test")public void test(Person person){System.out.println(person);}}
application/x-www-form-urlencoded方式的表单提交,后端可以直接使用实体类接收,但是要注意HTML中的input的name属性值要对应实体类的属性名。
application/json方式
使用AJAX提交JSON格式的数据是很常见的,处理的方式也较为简单
前端JS如下:
function submit() {$.ajax({type: 'POST',url: 'http://localhost:8089/form/test',// 传送到后端应为JSON格式字符串,使用JSON的stringify方法格式化data: JSON.stringify({name: $("#name"),age: $("#age")}),// 必须为该格式contentType: 'application/json',dataType: 'json',success: (res) => {alert(res);}});}
后端接收,只需要在参数前添加@RequestBody注解,Spring会自动解析映射。
@PostMapping("/test")public void test(@RequestBody Person person){System.out.println(person);}
multipart/form-data
当设置成 multipart/form-data 时,浏览器不对字符进行编码,每一个域都是一个part、这种编码方式通常适用于上传文件。
当不上传文件,只提交表单数据时,后端接收方式与application/x-www-form-urlencoded一致。
当既要上传文件又要提交额外的数据时,前端可以使用FormData对象封装参数。
单文件上传
直接使用from表单提交,前端如下:
<form id="form">file<input type="file" id="file" name=file>name<input type="text" name="name" id="name">age<input type="text" name="age" id="age">submit<input type="submit"></form>
后端:
@PostMapping("/file")public void fileTest(@RequestParam("file") MultipartFile file, Person person){System.out.println(person);System.out.println(file.getOriginalFilename());}
multipart/form-data这种方式提交时,参数都是binary类型

通过AJAX使用FormData对象封装参数后提交,前端JS如下:
function submit() {let formData = new FormData();let file = $("#file")[0].files[0];formData.append("name", $("#name2").val());formData.append("age", $("#age2").val());console.log(formData);$.ajax({type: 'POST',url: 'http://localhost:8089/form/files',data: formData,cache: false,processData: false,contentType: false,dataType: 'json',success: (res) => {alert(res);}});}
将Person的参数拼接进FormData对象中,提交的时候,name和age的参数不再是binary。但Spring同样可以像上面那种方式一样将参数解析出来。注意append时的key值对应实体类属性名。
后端如下方式接收:
@PostMapping("/file")public void fileTest(@RequestParam("file") MultipartFile file, Person person){System.out.println(person);System.out.println(file.getOriginalFilename());}
还有一种更加优雅的方式,将Person拼接的时候也使用binary格式,但要指定type为application/json
function submit() {let formData = new FormData();let file = $("#file")[0].files[0];let person = {name: $("#name2").val(),age: $("#age2").val()}// 将person转为json字符串formData.append('person', new Blob([JSON.stringify(person)], { type: 'application/json' }));console.log(formData);$.ajax({type: 'POST',url: 'http://localhost:8089/form/files',data: formData,cache: false,processData: false,contentType: false,dataType: 'json',success: (res) => {alert(res);}});}
后端接收时使用@RequestPart注解将映射Person参数
@PostMapping("/files")public void fileTest(@RequestParam("file") MultipartFile file, @RequestPart("person") Person person){System.out.println(person);System.out.println(file.getOriginalFilename());}
多文件上传
前端有两种写法、一种是使用HTML5的multiple属性创建一个支持多选文件的上传框,一种是写多个上传框。
- 第一种:HTML5的multiple属性创建一个支持多选文件的上传框
<form id="form">file<input type="file" multiple="multiple" id="files" name=files>name<input type="text" name="name" id="name">age<input type="text" name="age" id="age"></form>
js如下
function submit() {let formData = new FormData();let files = $("#files");let person = {name: $("#name").val(),age: $("#age").val()}// 循环遍历files输入框、拼接文件内容到formDatafor (let i = 0; i < files[0].files.length; i++) {formData.append("files", files[0].files[i]);}formData.append('person', new Blob([JSON.stringify(person)], { type: 'application/json' }));console.log(formData);$.ajax({type: 'POST',url: 'http://localhost:8089/form/files',data: formData,cache: false,processData: false,contentType: false,dataType: 'json',success: (res) => {alert(res);}});}
- 使用多个上传框
<form id="form">file<input type="file" name=files id="file1">file<input type="file" name=files id="file2">name<input type="text" name="name" id="name2">age<input type="text" name="age" id="age2"></form>
js代码如下
function submit2() {let formData = new FormData();let file1 = $("#file1")[0].files[0];let file2 = $("#file2")[0].files[0];let person = {name: $("#name2").val(),age: $("#age2").val()}formData.append("files", file1);formData.append("files", file2);formData.append('person', new Blob([JSON.stringify(person)], { type: 'application/json' }));console.log(file1);$.ajax({type: 'POST',url: 'http://localhost:8089/form/files',data: formData,cache: false,processData: false,contentType: false,dataType: 'json',success: (res) => {alert(res);}});}
后端接收方式第一样、只需要将接收文件的MultipartFile设为数组即可
@PostMapping("/files")public void fileTest(@RequestParam("files") MultipartFile[] files, @RequestPart("person") Person person){System.out.println(person);System.out.println(files.length);}
