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

Spring Boot DELETE/PUT报CORS无Access-Control-Allow-Origin错

问题根因

DELETE、PUT、带Authorization自定义头/Content-Type: application/json的请求属于非简单请求,浏览器会先发送OPTIONS方法的预检请求,校验跨域头通过后才会发真实业务请求。Postman不会发送预检请求,所以直接调用接口正常。
你当前的问题有两个核心错误:

  • 前端错误在请求头中添加了仅后端可返回的Access-Control-Allow-Origin响应头,额外触发了跨域校验
  • 后端跨域配置未覆盖OPTIONS预检请求,若使用Spring Security等安全框架,预检请求会被优先拦截,导致Controller层的@CrossOrigin注解完全不生效

修复步骤

1. 修正前端代码

删除前端请求头中错误的Access-Control-Allow-Origin字段,这个字段是后端返回给浏览器的响应头,前端禁止手动携带。修正后的代码如下:

export async function deleteUser(id, token) {
  console.log("helo")
  const response = await fetch(`${URL}/users/${id}`, {
      method: "DELETE",
      mode: 'cors',
      headers: {
          "content-type": "application/json",
          "authorization": `Bearer ${token}`
          // 移除Access-Control-Allow-Origin配置
      }
  })

  if (!response.ok) {
      return Promise.reject(response)
  }
  // 补充原有响应解析逻辑,例如return response.json()
}

不要尝试设置mode: 'no-cors'绕过跨域,该模式下前端无法读取接口响应内容,无实际业务意义。

2. 配置后端全局跨域过滤器

不要仅依赖Controller上的@CrossOrigin注解,全局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() {
        CorsConfiguration config = new CorsConfiguration();
        // 允许前端源地址,禁止用通配符*,因为携带Authorization凭据时通配符配置无效
        config.addAllowedOrigin("http://localhost:3000");
        // 允许携带凭据(Authorization头、Cookie等)
        config.setAllowCredentials(true);
        // 放行所有请求方法,包含OPTIONS预检、DELETE、PUT、PATCH等
        config.addAllowedMethod("*");
        // 放行所有请求头
        config.addAllowedHeader("*");
        // 预检请求缓存时间,单位秒,有效期内无需重复发送预检请求
        config.setMaxAge(3600L);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有接口路径生效
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

3. 适配Spring Security配置(若项目引入了安全框架)

Spring Security的过滤器链优先级高于普通Web过滤器,若不额外配置,OPTIONS预检请求会被安全框架拦截返回401/403,跨域配置无法生效。修改Security配置类:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            // 启用CORS,自动加载之前配置的跨域过滤器
            .cors(cors -> {})
            // 关闭CSRF校验,避免DELETE/PUT等非POST请求被拦截
            .csrf(csrf -> csrf.disable())
            .authorizeHttpRequests(auth -> auth
                // 所有OPTIONS预检请求直接放行,不做权限校验
                .requestMatchers(HttpMethod.OPTIONS, "/**").permitAll()
                // 保留原有业务接口的权限配置
                .anyRequest().authenticated()
            );
        return http.build();
    }
}

验证方式

重启后端服务后发起请求,打开浏览器开发者工具的Network面板:

  • 先找到OPTIONS类型的预检请求,确认其响应状态码为200/204,响应头包含Access-Control-Allow-Origin: http://localhost:3000、Access-Control-Allow-Methods: DELETE,PUT,GET,POST等字段
  • 预检请求通过后,后续真实DELETE/PUT请求即可正常响应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 01:18:49