使用Fetch API上传图片至Spring Boot服务器报404错误的求助
Hey,我之前也碰到过类似的上传图片404的问题,结合你的代码和常见的坑,给你梳理几个排查方向和解决方案,应该能帮你解决问题:
首先先把你的前端代码整理完整(方便参考):
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <title>Document</title> <script type="text/javascript" th:inline="javascript"> function submitImage() { const name = document.querySelector('input[name="name"]').value; const image = document.querySelector('input[type="file"]').files[0]; const formData = new FormData(); formData.append('image', image); formData.append('name', name); fetch('/add', { method: 'POST', body: formData }) .then(response => { console.log(response) // 这里可以补充处理成功/失败的逻辑 }) .catch(error => { console.error('上传出错啦:', error); }); } </script> </head> <body> <input type="text" name="name" placeholder="输入名称"/> <input type="file" accept="image/*" /> <button onclick="submitImage()">上传图片</button> </body> </html>
接下来是具体的排查点:
1. 后端接口路径和请求方法完全匹配了吗?
这是404最常见的原因!你得确保Spring Boot的Controller接口和前端请求的/add完全对应:
- 检查Controller的请求路径:如果Controller类上有
@RequestMapping("/api")这类前缀,那方法上的路径得是@PostMapping("/add"),此时前端请求路径应该是/api/add,不然肯定找不到。 - 必须用POST方法:接口方法上要加
@PostMapping("/add"),或者@RequestMapping(value = "/add", method = RequestMethod.POST),用GET的话POST请求肯定会404。
给你一个正确的Controller示例:
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @RestController public class ImageUploadController { @PostMapping("/add") public String uploadImage(@RequestParam("image") MultipartFile imageFile, @RequestParam("name") String name) { // 这里写你的上传逻辑,比如保存图片到服务器或者OSS if (!imageFile.isEmpty()) { System.out.println("收到图片:" + imageFile.getOriginalFilename()); System.out.println("名称:" + name); return "上传成功!"; } return "上传失败,图片为空"; } }
2. 有没有配置上下文路径?
如果你的Spring Boot项目在application.properties里配置了server.servlet.context-path=/myapp(比如给项目加了个前缀),那前端请求的路径必须加上这个前缀,比如fetch('/myapp/add', ...)。
为了避免硬编码,你可以用Thymeleaf的语法动态获取上下文路径,这样不管怎么配置都不会错:
// 用Thymeleaf的内联语法获取上下文路径 const contextPath = /*[[@{/}]]*/ ''; fetch(contextPath + 'add', { method: 'POST', body: formData })
3. 是不是跨域问题导致的“假404”?
如果你的前端是直接打开本地HTML文件(用file://协议),或者前端和后端运行在不同端口(比如前端8080,后端8081),那浏览器会因为跨域拦截请求,有时候表现出来也是404,但实际是跨域的问题。
解决这个的话,给你的Controller加个@CrossOrigin注解就行:
@RestController @CrossOrigin(origins = "*") // 开发环境可以用*,生产环境建议指定具体的前端域名 public class ImageUploadController { // 接口方法... }
4. Multipart文件配置有没有问题?
Spring Boot默认已经配置了Multipart的处理,但如果你的图片太大,可能会有问题,你可以在application.properties里调整一下:
# 允许单个文件最大10MB spring.servlet.multipart.max-file-size=10MB # 允许整个请求最大10MB spring.servlet.multipart.max-request-size=10MB
5. Controller有没有被Spring扫描到?
检查你的Controller类是不是在Spring Boot主类的包或者子包下面,比如主类是com.example.MyApplication,那Controller最好放在com.example.controller这样的子包里,不然Spring找不到这个Controller,自然也就没有接口了。如果不在同一包下,记得在主类上加上@ComponentScan(basePackages = "你的Controller所在包路径")。
备注:内容来源于stack exchange,提问作者yayayaya

