Angular8向Spring Boot传图报错:Current request is not a multipart request
解决方案:Angular + Spring Boot 上传文件+表单数据+JWT认证问题
我来帮你解决这个问题,你遇到的两个核心问题——Current request is not a multipart request报错和CORS错误,其实是关联的,咱们一步步拆解:
问题根源分析
手动设置Content-Type导致的Multipart请求失败:
当你用Angular的HttpClient发送FormData时,浏览器会自动生成正确的multipart/form-data请求头,其中包含关键的boundary分隔符(用来区分不同的表单字段)。但如果你手动设置Content-Type: multipart/form-data,会覆盖浏览器自动生成的头,而且没有带上boundary,后端就无法识别这是一个合法的Multipart请求,所以抛出错误。CORS错误的原因:
后端没有配置正确的跨域规则,尤其是没有允许你前端的域名发起请求,也没有允许携带Authorization头(因为JWT认证需要这个头)。
具体解决方案
1. 前端代码修改(关键:去掉手动设置的Content-Type)
修改你的InscriptionService,不要手动指定Content-Type,同时添加JWT认证头:
import { Injectable } from '@angular/core'; import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class InscriptionService { mainUrl: string = "http://192.168.1.70:8080/"; constructor(private httpClient: HttpClient) { } inscription(formData: FormData): Observable<any> { // 从本地存储或其他地方获取你的JWT Token const jwtToken = localStorage.getItem('auth_token'); // 只设置Authorization头,不要手动设置Content-Type! const headers = new HttpHeaders({ 'Authorization': `Bearer ${jwtToken}` }); // HttpClient会自动为FormData生成正确的multipart/form-data头(包含boundary) return this.httpClient.post(`${this.mainUrl}inscription`, formData, { headers }); } }
2. 后端配置调整
方式一:接口级别的CORS配置(快速测试)
在你的接口方法上添加@CrossOrigin注解,允许前端域名和必要的请求头:
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; // 替换成你的Angular前端地址(比如http://localhost:4200) @CrossOrigin(origins = "http://your-angular-domain:port", allowedHeaders = "*", methods = {RequestMethod.POST}, allowCredentials = "true") @RequestMapping(value="/inscription", method=RequestMethod.POST) public boolean inscription(@RequestParam("file") MultipartFile[] file,@RequestParam("user") String user ) throws IOException{ saveUploadedFiles(file); System.out.println(file[0].toString()); User userf = new ObjectMapper().readValue(user, User.class); System.out.println(userf.getEmail()); System.out.println("hello"); return true; }
方式二:全局CORS配置(推荐,适合多接口场景)
创建一个全局的CORS配置类,统一处理跨域请求:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class GlobalCorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 允许的前端域名,多个可以用逗号分隔 .allowedOrigins("http://your-angular-domain:port") // 允许的请求方法 .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许所有请求头(包括Authorization) .allowedHeaders("*") // 允许携带Cookie(如果你的JWT存在Cookie里) .allowCredentials(true) // 预检请求的缓存时间 .maxAge(3600); } }
可选:配置Multipart参数(防止大文件上传失败)
在application.properties里添加以下配置,调整文件上传的大小限制:
# 单个文件最大大小 spring.servlet.multipart.max-file-size=10MB # 整个请求的最大大小 spring.servlet.multipart.max-request-size=10MB
验证步骤
- 确保前端构造
FormData时,字段名和后端@RequestParam的名称一致(比如file和user):// 示例:前端构造FormData的代码 const formData = new FormData(); formData.append('file', fileObject); // fileObject是你的文件对象 formData.append('user', JSON.stringify(userObject)); // userObject是你的用户对象,转成JSON字符串 - 启动前后端服务,重新发送请求,应该就能正常上传文件和表单数据了。
内容的提问来源于stack exchange,提问作者Amr Elha
相关产品推荐
相关产品推荐

