开发环境:后台使用springboot框架,IDE使用idea,使用jquery与ajax方法实现将文件上传到本地的相应目录中。
1、前端html页面
前端上传文件时可以使用三种方法:
-
1、使用form标签中的 action 方法提交上传文件,这时表单提交成功后默认页面会自动进行跳转。
-
2、使用form标签,但使用ajax提交上传文件,页面不跳转。
-
3、不使用form标签,但使用ajax提交上传文件,页面不跳转。
-
尝试直接使用jquery.post()方法进行文件上传,会报 illegal invocation 错误,查找原因如下;
- 因为jquery.post()方法没有设置contentType:false与 processData:false
- processData设置为true会使传递的参数被处理
- contentType为true会使,其自动设置请求头类型
方法1的html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" enctype="multipart/form-data" action="http://localhost:8099/upload">
<p>请选择要上传的文件:</p>
<p><input type="file" name="file" /></p>
<p><input type="submit" value="上传" /></p>
</form>
<!--以上代码中,`<form>`的`method`属性值必须是`post`,`enctype`属性值必须是`multipart/form-data`,且上传控件的`type`属性值必须是`file`。-->
</body>
</html>
表单提交成功后默认页面会自动进行跳转。
方法2与方法3的html代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function () {
//使用ajax传输表单内的formdata的文件
$("#upload").click(function () {
console.info("click");
$.ajax({
url: 'http://localhost:8099/upload',
type: 'POST',
cache: false,
data: new FormData($('#uploadForm')[0]),
//ajax2.0可以不用设置请求头,但是jq帮我们自动设置了,这样的话需要我们自己取消掉
processData: false,
//取消帮我们格式化数据,是什么就是什么
contentType: false,
success:function (res) {
alert(res);
}
});
});
//使用ajax提交不在表单内的文件
$("#upload2").click(function () {
//相比使用form多了这两句
var formData = new FormData();
formData.append('file', $('#file2')[0].files[0]);
$.ajax({
url: 'http://localhost:8099/upload',
type: 'POST',
cache: false,
data: formData,
//ajax2.0可以不用设置请求头,但是jq帮我们自动设置了,这样的话需要我们自己取消掉
processData: false,
//取消帮我们格式化数据,是什么就是什么
contentType: false,
success:function (res) {
alert(res);
}
});
});
//测试直接使用jquery.post方法提交,实测不成功,需要使用前两种方式
// $("#upload3").click(function () {
// var formData = new FormData();
// formData.append('file', $('#file3')[0].files[0]);
// $.post("http://localhost:8099/upload",formData,function (res) {
// alert(res);
//
// });
//
// });
})
</script>
</head>
<body>
<!--使用表单提交文件-->
<form id="uploadForm" enctype="multipart/form-data">
<input id="file" type="file" name="file"/>
<button id="upload" type="button">upload</button>
</form>
<!--不使用表单提交文件-->
<div id="uploadForm2">
<input id="file2" type="file"/>
<button id="upload2" type="button">upload2</button>
</div>
<!--测试直接使用jquery.post方法提交,实测失败-->
<!--<div id="uploadForm3">-->
<!-- <input id="file3" type="file"/>-->
<!-- <button id="upload3" type="button">upload3</button>-->
<!--</div>-->
</body>
</html>
2、后端controller代码
package com.example.activity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@RestController
public class UploadController {
@RequestMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file,
HttpServletRequest request)
throws IllegalStateException, IOException {
System.out.println("UploadController.upload()");
// 判断上传的文件是否为空
boolean isEmpty = file.isEmpty();
System.out.println("\tisEmpty=" + isEmpty);
if (isEmpty) {
throw new RuntimeException("上传失败!上传的文件为空!");
}
// 检查文件大小
long fileSize = file.getSize();
System.out.println("\tsize=" + fileSize);
if (fileSize > 1 * 1024 * 1024) {
throw new RuntimeException("上传失败!上传的文件大小超出了限制!");
}
// 检查文件MIME类型
String contentType = file.getContentType();
System.out.println("\tcontentType=" + contentType);
//下面的代码限定上传文件的类型为图片格式,可以结合实际使用
// List<String> types = new ArrayList<String>();
// types.add("image/jpeg");
// types.add("image/png");
// types.add("image/gif");
// if (!types.contains(contentType)) {
// throw new RuntimeException("上传失败!不允许上传此类型的文件!");
// }
// 准备文件夹,获取项目中upload文件夹的路径
// String parentDir = request.getServletContext().getRealPath("upload");
File directory = new File("");//设定为当前文件夹
String parentDir=directory.getAbsolutePath()+"\\src\\main\\resources\\static\\uploadFile";
System.out.println("\tpath=" + parentDir);
File parent = new File(parentDir);
if (!parent.exists()) {
parent.mkdirs();
}
// 获取原始文件名
String originalFilename = file.getOriginalFilename();
System.out.println("\toriginalFilename=" + originalFilename);
// 确定最终保存时使用的文件
String filename = UUID.randomUUID().toString();
String suffix = "";
int beginIndex = originalFilename.lastIndexOf(".");
if (beginIndex != -1) {
suffix = originalFilename.substring(beginIndex);
}
// 执行保存文件
File dest = new File(parent, filename + suffix);
file.transferTo(dest);
return "sucess";
}
}
参考:
SpringMVC和SpringBoot实现上传文件保存到服务器
通过Ajax方式上传文件,使用FormData进行Ajax请求
使用AJAX实现文件上传时illegal invocation错误的原因及解决方案