表单提交与后端接收
HTML中的表单有几个重要的属性,分别是action
、method
、enctype
- action:用于设定表单提交的服务器的 URL,可以是相对路径和绝对路径。
- method:用于设定 HTTP 请求的方式。
- enctype:用于定义表单数据提交到服务器的过程中如何对数据进行编码
本次主要针对enctype进行测试实验。method统一使用POST
方式。
后端使用SpringBoot2.x,Spring在参数处理方面已经做了很好的处理了。
SpringBoot上传文件的一些基本设置
#是否开启文件上传支持,默认是true
spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-request-size=100MB
spring.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>
后端接收方式
// 实体类
@Data
public 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输入框、拼接文件内容到formData
for (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);
}