如何让Angular与Spring搭建的REST API在同一机器正常协作?
解决Spring Boot API与Angular跨域的CORS问题
这问题我熟!你碰到的是浏览器同源策略导致的CORS跨域问题——前端Angular跑在localhost:4200,后端Spring API在localhost:8080,俩端口不一样,浏览器就会默认阻止跨域请求,除非后端明确允许这个源的访问。给你几个靠谱的解决办法,按需选就行:
一、在Spring Boot后端配置CORS(推荐生产/开发都用)
1. 全局配置(给整个API应用开权限)
建一个配置类,让所有接口都自动支持来自Angular的请求:
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 匹配所有API路径 .allowedOrigins("http://localhost:4200") // 允许Angular的源地址 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP请求方法 .allowedHeaders("*") // 允许所有请求头 .allowCredentials(true); // 如果需要携带Cookie就开这个,不需要可以去掉 } }
写完重启Spring项目,所有接口都会自动带上Access-Control-Allow-Origin这类CORS响应头,浏览器就不会拦你的请求了。
2. 控制器/接口单独配置(只给特定API开权限)
要是只想给某个控制器或者某一个接口开跨域权限,直接加@CrossOrigin注解就行:
import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.http.ResponseEntity; @RestController @RequestMapping("/org") @CrossOrigin(origins = "http://localhost:4200") // 给整个控制器下的所有接口开跨域 public class OrganizationController { @GetMapping("/getRecord") // 也可以单独给这个方法加:@CrossOrigin(origins = "http://localhost:4200") public ResponseEntity<?> getRecord() { // 你的业务逻辑代码 return ResponseEntity.ok("获取到的记录数据"); } }
3. 自定义过滤器配置(更底层的控制)
如果需要更灵活的配置,比如处理复杂的预检请求,就自定义一个CORS过滤器:
import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class CorsFilter implements Filter { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; HttpServletRequest request = (HttpServletRequest) req; // 设置允许的源 response.setHeader("Access-Control-Allow-Origin", "http://localhost:4200"); // 设置允许的请求方法 response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 设置允许的请求头 response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); // 允许携带Cookie response.setHeader("Access-Control-Allow-Credentials", "true"); // 处理预检请求(OPTIONS方法),直接返回200 if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); } else { chain.doFilter(req, res); } } }
这个过滤器会在每个请求到达时自动添加CORS响应头,处理浏览器发送的预检请求。
二、Angular端配置代理(开发环境临时方案)
要是不想改后端代码,只在开发环境用的话,可以给Angular加个代理,把API请求转发到后端:
- 在Angular项目根目录新建
proxy.conf.json文件,内容如下:
{ "/org": { "target": "http://localhost:8080", "secure": false, "changeOrigin": true } }
- 修改
package.json里的启动命令,加上代理配置:
"scripts": { "start": "ng serve --proxy-config proxy.conf.json", // 其他命令保持不变 }
- 重启Angular项目,之后前端调用API的时候,直接用相对路径
/org/getRecord/就行,Angular会自动把请求转发到http://localhost:8080/org/getRecord/,这样就绕开了跨域问题。
注意:这个方法只适合开发环境,上线生产环境还是得靠后端配置CORS或者用Nginx反向代理统一处理。
内容的提问来源于stack exchange,提问作者user3292629
相关产品推荐
相关产品推荐

