注意: formData为H5中提出的,所以老版本的浏览器可能不支持(例如:IE等)
鉴于网上一大堆异步上传文件没有讲清楚,特意作如下笔记,以防忘记:
前端代码部分:
<html>
<head>
<title>文件上传案例</title>
<script src="${pageContext.request.contextPath}/js/axios.min.js"></script>
</head>
<body>
<!--
上传文件需要将enctype改为multipart/form-data
文件操作必须为POST请求
-->
<h3>异步Ajax方式(axios)</h3>
<div>
<input type="file" id="filepath"/>
<input type="button" id="fileuploadBtn" value="文件上传"/>
</div>
<script>
document.getElementById("fileuploadBtn").addEventListener('click', function (event) {
// 通过file表单的files数组属性,获取文件二进制流
let filepath = document.getElementById("filepath").files[0];
// 注意: formData为H5中提出的,所以老版本的浏览器可能不支持(例如:IE等)
// formData从官网上得知,是以Key/Value方式设置值得
// 结果网上一大堆搓逼,没一个把formData讲清楚的
// 这里append中'filepath'即为file表单元素的name, 与服务端的参数key匹配才能接收数据
let formData = new FormData()
formData.append('filepath',filepath)
axios({
url:".../fileuploadAjax", // 采用了超级原始的EL表达式
method: "post",
data: formData,
/*headers: { // 经过测试,其实不需要设置该请求头,服务端一样能接收二进制数据流
'Content-Type': 'multipart/form-data'
}*/
}).then((res)=>{
console.log(res)
});
});
</script>
</body>
</html>
后端SpringMVC部分:
/**
* 文件上传操作, 文件操作必须为POST请求(异步操作)
* @param filepath SpringMVC封装的上传组件对象: 该参数与前端的formData对象中append里设置的key对应,才能被匹配接收
* (可以观察请求体来测试)
* 我这里测试如果没有加MultipartConverters组件, 并不会报错,但是无法获得MultipartFile(即为null)
* 如采用了commons-fileupload,则需要引入commons-fileupload和commons-io俩个jar依赖包
*/
@RequestMapping(value = "/fileuploadAjax", method = RequestMethod.POST)
@ResponseBody
public String fileupload2(MultipartFile filepath, HttpSession session) throws IOException {
// 获得上传的文件名
String originalFilename = filepath.getOriginalFilename();
System.out.println("上传的文件名为: " + originalFilename);
// 获得file表单的name值
String name = filepath.getName();
System.out.println("File表单的name值: " + name);
// 使用UUID设置随机不重复的名字,以便用于保存文件
String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
// 保存路径为项目目录下的photo文件夹
String photo = session.getServletContext().getRealPath("photo");
File file = new File(photo);
// 判断存放路径是否存在,如果不存在,则创建
if(!file.exists()){
file.mkdirs();
}
// 拼装保存文件路径(包括文件名)
StringBuffer sbf = new StringBuffer();
String saveFilePath = sbf.append(photo).append(File.separator).append(fileName).toString();
/**
* 方式1. 可以通过IO流将文件写入到服务器磁盘中
*/
/*InputStream is = fileUpload.getInputStream();
OutputStream os = new BufferedOutputStream(new FileOutputStream(saveFilePath));
byte[] bytes = new byte[1024];
int len = -1;
while((len = is.read(bytes)) != -1){
os.write(bytes, 0, len);
}
os.close();
is.close();*/
/**
* 方式2. 直接使用MultipartFile的transferTo方法
*/
filepath.transferTo(new File(saveFilePath));
return "上传成功";
}