You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Angular 5客户端向Spring Boot后端服务传输文件?

解决Angular 5上传文件到Spring Boot的CORS 403问题

看起来你在文件上传的跨域请求上踩了两个关键的坑,一个在前端请求格式,一个在后端CORS配置的细节上。咱们一步步来修复:

1. 先修正Angular服务的请求错误

你现在的代码里把FormData用JSON.stringify()包裹了,这完全破坏了multipart请求的格式——文件上传必须用原生的FormData对象传递,不能转成JSON。修改你的服务代码:

@Injectable()
export class UploadFileService {
  constructor(private httpClient: HttpClient, private globals: Globals) { }

  pushFileToStorage(file: File) {
    const formData = new FormData();
    formData.append('file', file);

    const req = this.httpClient.post(
      `http://localhost:${this.globals.tomcatPort}/utils/saveFromFile`,
      formData // 直接传FormData,不要转JSON
    );

    req.subscribe(
      (data) => console.log('上传成功:', data),
      (err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          console.log('客户端错误:', err.error.message);
        } else {
          console.log('后端错误:', err.status, err.error);
        }
      }
    );
  }
}

另外别手动加Headers,HttpClient会自动为FormData请求设置正确的multipart/form-data头(包括自动生成的boundary分隔符),手动设置反而容易出问题。

2. 修复Spring Boot的CORS与Multipart配置

你的@CrossOrigin注解在处理multipart请求的OPTIONS预检时可能失效了,尤其是当你配置了MultipartFilter的情况下,过滤器顺序会导致CORS头没被正确添加。推荐改用全局CORS配置,更可靠:

新增全局CORS配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        
        config.addAllowedOrigin("http://localhost:4200");
        config.addAllowedMethod("*"); // 允许所有请求方法
        config.addAllowedHeader("*"); // 允许所有请求头
        config.setAllowCredentials(true);
        config.setMaxAge(3600L); // 预检请求缓存1小时
        
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

然后把Controller上的@CrossOrigin注解删掉,全局配置已经覆盖了这部分功能。

修正MultipartFilter的拼写错误

你代码里的multipartResolverBeanName有隐藏的特殊字符,导致Spring找不到对应的Resolver,修正后:

@Bean
@Order(0)
public MultipartFilter multipartFilter() {
    MultipartFilter multipartFilter = new MultipartFilter();
    // 修正拼写错误,去掉隐藏字符
    multipartFilter.setMultipartResolverBeanName("multipartResolver");
    return multipartFilter;
}

改用Spring原生的MultipartResolver(可选但推荐)

Spring Boot 2.x+推荐使用基于Servlet 3.0的StandardServletMultipartResolver,比Apache Commons的实现更轻量,替换你原来的CommonsMultipartResolver:

@Bean
public StandardServletMultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

同时在application.properties里添加文件上传限制:

spring.servlet.multipart.max-file-size=3MB
spring.servlet.multipart.max-request-size=3MB

问题根源总结

  1. 前端错误地将FormData转成JSON,导致请求格式完全不符合multipart要求,触发了异常的预检请求;
  2. 后端@CrossOrigin在处理multipart的OPTIONS预检时,因为过滤器顺序问题(MultipartFilter先执行),没有正确添加CORS头,返回403;
  3. MultipartFilter的bean名称拼写错误,导致文件解析逻辑失效。

按上面的步骤修复后,应该就能正常完成文件上传了。

内容的提问来源于stack exchange,提问作者Matexon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:19:13