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

React向SpringBoot+MongoDB发POST请求时遇415及CORS错误

解决方案:React图片上传到SpringBoot后端的CORS与415/403错误处理

错误原因分析

  1. 403 + CORS错误:SpringBoot端未正确配置跨域规则,或SpringSecurity拦截了跨域预检(OPTIONS)请求及上传接口,导致权限拒绝。
  2. 415 + CORS错误:后端接口参数接收方式错误(如误用@RequestBody处理multipart/form-data),或前端手动设置Content-Type导致请求边界(boundary)丢失,后端无法解析表单数据;同时跨域配置仍存在漏洞。
  3. no-cors模式无效:该模式仅限制浏览器对响应的读取,无法解决后端的跨域配置问题,反而会阻碍调试。

分步解决

1. 修正前端请求代码(React)

不要手动设置Content-Type,FormData会自动生成带正确boundary的multipart/form-data请求头;确保请求携带必要凭证(如需要):

const handleUpload = async (e) => {
  e.preventDefault();
  const formData = new FormData();
  // 追加文件与其他表单字段
  formData.append('uploadFile', document.getElementById('fileInput').files[0]);
  formData.append('title', '测试图片');

  try {
    const res = await fetch('http://localhost:8080/api/upload', {
      method: 'POST',
      credentials: 'include', // 若后端需要Cookie则开启
      body: formData
      // 无需手动设置Content-Type,浏览器自动处理
    });
    const result = await res.json();
    console.log('上传成功:', result);
  } catch (err) {
    console.error('上传失败:', err);
  }
};

2. 修正后端接口与跨域配置(SpringBoot)

方式一:接口级跨域配置

直接在上传接口上添加@CrossOrigin,明确允许跨域来源、请求方法与头部:

@RestController
@RequestMapping("/api")
public class UploadController {

    @PostMapping("/upload")
    @CrossOrigin(origins = "http://localhost:3000", // React项目地址
                 allowedHeaders = "*",
                 methods = {RequestMethod.POST, RequestMethod.OPTIONS})
    public ResponseEntity<String> upload(
            @RequestPart("uploadFile") MultipartFile file,
            @RequestPart("title") String title) {
        // 处理MongoDB存储逻辑(如使用GridFS存储文件)
        return ResponseEntity.ok("文件上传成功:" + file.getOriginalFilename());
    }
}

注意:必须用@RequestPart接收文件与表单字段,不能用@RequestBody(后者仅处理JSON格式数据)。

方式二:全局跨域配置

若多个接口需要跨域,推荐全局配置:

@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "OPTIONS", "DELETE", "PUT")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600); // 预检请求缓存时长
    }
}

3. SpringSecurity兼容配置(若使用)

如果项目集成了SpringSecurity,需放行OPTIONS预检请求与上传接口,同时启用CORS:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors() // 启用CORS配置
                .and()
                .csrf().disable() // 若无需CSRF保护可关闭,或配置CSRF令牌
                .authorizeRequests()
                .antMatchers("/api/upload").permitAll() // 放行上传接口
                .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // 放行预检请求
                .anyRequest().authenticated();
    }

    // 注入全局CORS配置
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        config.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS"));
        config.setAllowedHeaders(Arrays.asList("*"));
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

4. 验证Multipart解析配置

SpringBoot默认已自动配置MultipartResolver,无需额外配置;若自定义了该Bean,确保配置正确:

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    resolver.setMaxUploadSize(10485760); // 设置最大上传大小(10MB)
    return resolver;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 17:53:08