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

如何让Angular的proxy.conf.json在Spring Boot中生效解决跨域问题

解决Angular+Spring Boot集成后proxy.conf.json不生效的跨域问题

问题的核心在于:Angular的proxy.conf.json是给Angular开发服务器(ng serve)用的,当你把Angular构建产物打包到Spring Boot的static目录后,是Spring Boot内置的Web服务器(比如Tomcat)在托管前端静态资源,这时候Angular的代理配置完全不会被加载——因为它根本不属于Spring Boot的配置体系。

下面给你几个生产环境可行的解决方案:

方案1:直接在Spring Boot中配置CORS(最简便)

如果外部API服务器允许跨域,或者你无法修改外部API的配置,最直接的方式是让Spring Boot放行前端的跨域请求:

全局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.addAllowedOriginPattern("*");
        // 允许携带Cookie(如果需要的话)
        config.setAllowCredentials(true);
        // 允许所有HTTP请求方法
        config.addAllowedMethod("*");
        // 允许所有请求头
        config.addAllowedHeader("*");
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有路径生效
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

局部接口配置

如果只想给特定接口开放跨域,在对应的Controller方法上添加@CrossOrigin注解:

@CrossOrigin(origins = "*", allowedHeaders = "*")
@GetMapping("/your-api-path")
public ResponseEntity<?> yourMethod() {
    // 业务逻辑
}

方案2:用Spring Boot做反向代理(替代Angular proxy)

如果你不想让前端直接暴露外部API地址,或者需要统一鉴权,可以让Spring Boot作为中间层转发请求,模拟Angular proxy的效果:

方式A:Spring Cloud Gateway(适合微服务场景)

  1. 先引入Gateway依赖(pom.xml):
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
  1. 在application.yml中配置路由规则:
spring:
  cloud:
    gateway:
      routes:
        - id: external_api_proxy
          # 外部API的基础地址
          uri: https://your-external-api-server.com
          # 匹配前端请求的路径前缀
          predicates:
            - Path=/api/external/**
          # 重写路径,去掉前缀/api/external
          filters:
            - RewritePath=/api/external/(?<segment>.*), /$\{segment}

这样前端请求/api/external/get-data,Spring Boot会自动转发到https://your-external-api-server.com/get-data,前端完全不需要修改请求地址。

方式B:自定义转发Controller(轻量方案)

如果不想引入额外依赖,可以自己写一个Controller来处理请求转发:

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.ServletUriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("/api/external")
public class ExternalApiProxyController {
    private final RestTemplate restTemplate;
    // 外部API的基础地址
    private static final String EXTERNAL_API_BASE = "https://your-external-api-server.com";

    public ExternalApiProxyController(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    @GetMapping("/**")
    public ResponseEntity<?> forwardGet(HttpHeaders headers, @RequestParam Map<String, String> params, HttpServletRequest request) {
        // 去掉前缀/api/external,拼接真实路径
        String path = ServletUriComponentsBuilder.fromRequest(request).getPath().replace("/api/external", "");
        HttpEntity<?> entity = new HttpEntity<>(headers);
        return restTemplate.exchange(EXTERNAL_API_BASE + path, HttpMethod.GET, entity, Object.class, params);
    }

    @PostMapping("/**")
    public ResponseEntity<?> forwardPost(@RequestBody Object body, HttpHeaders headers, HttpServletRequest request) {
        String path = ServletUriComponentsBuilder.fromRequest(request).getPath().replace("/api/external", "");
        HttpEntity<?> entity = new HttpEntity<>(body, headers);
        return restTemplate.exchange(EXTERNAL_API_BASE + path, HttpMethod.POST, entity, Object.class);
    }

    // 可根据需求添加PUT、DELETE等方法
}

别忘了注册RestTemplate Bean:

@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

方案3:硬编码API地址(不推荐,仅临时测试)

如果只是临时测试,可以在Angular的生产环境配置中直接写外部API的完整地址,比如environment.prod.ts:

export const environment = {
  production: true,
  apiUrl: 'https://your-external-api-server.com'
};

但这种方式会直接触发跨域,还是需要外部API开启CORS或者Spring Boot配置CORS,生产环境不建议硬编码地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:17:26