共计 3569 个字符,预计需要花费 9 分钟才能阅读完成。
唠嗑部分
上篇文章我们说了使用 form 表单的 input 文件域上传文件,上篇文章:
但是现在随着前后端分离的开发方式,这种方式越来越少见了,对于后端工程师来说,接口层并没有多大变化,对于前端工程师、亦或者是干全栈的同学们来说,ajax 已经不再陌生,那我们本节就来说说,ajax 实现文件上传及文件预览
首先来说 FormData 与 FileReader 的使用,都是 HTML5 新增的 API
FormData
FormData 接口提供了一种表示表单数据的键值对 key/value
的构造方式,并且可以轻松的将数据通过 XMLHttpRequest.send() 方法发送出去,如果发送请求时的编码类型被设为 "multipart/form-data"
,它会使用和表单一样的格式。
构造函数
var fd = new FormData(form)
常用 api
fd.append(key,value);
fd.set(key,value);
fd.get(key);
fd.getAll(key);
fd.delete(key);
fd.has(key);
FileReader
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件内容,使用 File
或 Blob
对象指定要读取的文件或数据。
构造函数
const fr = new FileReader();
常用 api
fr.readAsDataURL(file);
fr.onload = () => {};
言归正传
1、创建项目 & 导入依赖
project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
parent>
artifactId>spring-boot-starter-parentartifactId>
groupId>org.springframework.bootgroupId>
version>2.4.2version>
relativePath/>
parent>
modelVersion>4.0.0modelVersion>
groupId>com.cxsgroupId>
artifactId>ajax-file-uploadartifactId>
version>1.0-SNAPSHOTversion>
properties>
maven.compiler.source>8maven.compiler.source>
maven.compiler.target>8maven.compiler.target>
properties>
dependencies>
dependency>
groupId>org.springframework.bootgroupId>
artifactId>spring-boot-starter-webartifactId>
dependency>
dependency>
groupId>org.projectlombokgroupId>
artifactId>lombokartifactId>
dependency>
dependencies>
project>
2、编写前端页面结构
DOCTYPE html>
html lang="en">
head>
meta charset="UTF-8">
title>ajax- 文件上传 title>
script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.3/jquery.min.js">script>
head>
body>
div>
form id="form">
用户名:input type="text" name="username"/>br/>
密码: input name="password" type="password"/>br/>
input id="file" type="file" name="file" style="display: none;"/>
label for="file">
img id="img" src="" title="+" width="300" height="150" style="cursor: pointer;"/>
label>
button> 上传 button>
form>
div>
body>
html>
3、后端接口部分
@PostMapping("/upload")
public MapString, Object> upload(User user, @RequestParam("file") MultipartFile file){
MapString, Object> result = new HashMap>();
result.put("code", 200);
try {
if (!ObjectUtils.isEmpty(file)) {
String originalFilename = file.getOriginalFilename();
if (StringUtils.hasLength(originalFilename)) {
String fullPath = PATH + File.separator + originalFilename;
File f = new File(fullPath);
if (!f.exists()) {
f.createNewFile();
}
file.transferTo(f);
user.setAvatar(fullPath);
result.put("data", fullPath);
result.put("user", user.toString());
}
} else {
result.put("code", 400);
result.put("msg", "文件不能为空!");
}
} catch (IOException e) {
e.printStackTrace();
result.put("code", 500);
result.put("msg", "文件上传失败!");
}
return result;
}
4、文件预览 -FileReader 的使用
详解请看注释
inp.addEventListener("change",function(){
const file = inp.files[0];
if(!file) {
img.src = currentPath;
currentFile = undefined;
return;
}
if(!file.type.startsWith("image")) return window.alert('请选择图片');
currentFile = file;
const fr = new FileReader();
fr.readAsDataURL(file);
fr.onload = () => {
console.log(fr.result)
img.src = fr.result;
}
})
5、文件上传 -FormData 的使用
Jquery 对于 ajax 的处理说明:
jQuery 帮我们做了封装,会将所有请求的请求头设置为 application/x-www-form-urlencoded, 而文件上传要求是 multipart/form-data
此时如果按照 jQuery 默认的就会出现问题
解决:不让 jQuery 帮我们设置就可以:contentType:false, 告诉 jQuery 不要设置我请求头里的 content-type
jQuery 还会帮我们把数据格式转化为 key=value 的形式
解决:不让 jQuery 自动格式化数据:processData:false, 告诉 jQuery 别帮我格式化数据
$("#form").submit(function (e){
e.preventDefault()
var formData = new FormData(this);
if(!currentFile) return window.alert("请选择文件再上传");
$.ajax({
url: '/upload',
type: 'post',
data: formData,
contentType : false,
processData : false,
success : (resp) => {
console.log(resp)
}
})
})
测试 & 结语
测试如下图
结语
1、本文采用 jQuery 作为 ajax 库,axios 大家可自行研究(类似)
2、源码获取方式, 全栈小白公众号后台回复:文件上传
原文地址: 【一文学会文件上传】SpringBoot JQuery-ajax 实现文件上传