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

Angular前端与Spring Boot微服务的CORS策略问题求助

问题:Angular与Spring Boot微服务间POST请求的CORS凭证问题

我正在构建基于Angular前端和多Spring Boot微服务的Web应用,向Spring Boot微服务发送POST请求时触发CORS策略错误,浏览器控制台报错:

Access to XMLHttpRequest at 'http://localhost:8082/publications/new' from origin 'http://localhost:4200' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

已尝试的配置:

  • 在微服务控制器添加@CrossOrigin(origins = "http://localhost:4200", allowCredentials = "true")注解
  • 在application.properties中配置CORS参数
  • Angular端配置带withCredentials=true的HTTP拦截器

相关代码

微服务控制器代码

@RestController
@CrossOrigin(origins = "http://localhost:4200", allowCredentials = "true")
@RequestMapping("/publications")
public class PublicationController {

     @Autowired
     private PublicationService publicationService;

@PostMapping("/new")
public ResponseEntity<Publication> createPublication(@RequestParam("file") MultipartFile file, @RequestParam("content") String content ,@RequestParam("username") String username) throws IOException {
    Publication publication = new Publication();
    publication.setContent(content);
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.set("Access-Control-Allow-Origin", "http://localhost:4200");
    responseHeaders.set("Access-Control-Allow-Credentials", "true");
    return new ResponseEntity<>(publicationService.createPublication(publication, file), responseHeaders, HttpStatus.CREATED);
}
}

Angular HTTP拦截器代码

import { Injectable } from '@angular/core';
 import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HTTP_INTERCEPTORS } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    req = req.clone({
      withCredentials: true,
    });

    return next.handle(req);
  }
}

export const httpInterceptorProviders = [
  { provide: HTTP_INTERCEPTORS, useClass: HttpRequestInterceptor, multi: true },
     ];

微服务application.properties配置

server.port=8082
spring.application.name=publication-service
eureka.client.service-url.defaultZone= http://localhost:8761/eureka
spring.datasource.url=jdbc:mysql://localhost:3307/jeee?useSSL=false
spring.datasource.username=root
spring.datasource.password=66pasS..
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
#pour ouvrir canal de connexion
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# Enable CORS
spring.mvc.cors.allow-credentials=true
spring.mvc.cors.allowed-origins=http://localhost:4200
spring.mvc.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
spring.mvc.cors.allowed-headers=*

问题原因分析

  1. 重复配置冲突:同时使用@CrossOrigin注解、全局CORS配置,以及手动在ResponseEntity中添加CORS响应头,导致Spring Boot处理请求时出现头信息覆盖或不一致的情况。
  2. 预检请求处理异常:文件上传的POST请求会触发OPTIONS预检请求,若配置未正确处理该请求的凭证头,会导致预检失败。
  3. 手动响应头优先级问题:ResponseEntity中手动添加的CORS头可能与Spring自动生成的头冲突,导致Access-Control-Allow-Credentials被清空。

解决方案

步骤1:清理重复配置,统一使用全局CORS配置

删除控制器上的@CrossOrigin注解,以及createPublication方法中手动设置的HttpHeaders,避免配置冲突。修改后的控制器代码:

@RestController
@RequestMapping("/publications")
public class PublicationController {

     @Autowired
     private PublicationService publicationService;

@PostMapping("/new")
public ResponseEntity<Publication> createPublication(@RequestParam("file") MultipartFile file, @RequestParam("content") String content ,@RequestParam("username") String username) throws IOException {
    Publication publication = new Publication();
    publication.setContent(content);
    return new ResponseEntity<>(publicationService.createPublication(publication, file), HttpStatus.CREATED);
}
}

步骤2:验证全局CORS配置

确认application.properties中的CORS配置包含OPTIONS方法(已配置),allowed-headers设为*已覆盖文件上传所需头信息,无需额外调整。

步骤3:备选方案:使用CORS配置类替代properties配置

若properties配置仍不生效,可创建全局CORS配置类精细控制规则,同时删除application.properties中的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();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:4200");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

步骤4:测试验证

重启微服务和Angular应用,重新发送请求。通过浏览器开发者工具的Network标签,查看OPTIONS和POST请求的响应头,确认Access-Control-Allow-Credentials为true、Access-Control-Allow-Origin为http://localhost:4200。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:07:51