Angular请求遭CORS拦截:缺失Access-Control-Allow-Origin头问题求助
SpringBoot + Angular 跨域(CORS)问题排查与修复
问题现象
SpringBoot服务端运行正常,但Angular前端请求http://localhost:8081/lecturers时触发CORS错误,提示XMLHttpRequest被CORS拦截,原因是缺少Access-Control-Allow-Origin头,服务端数据无法在前端展示。
前端(Angular)代码
模板文件(lecturers.component.html)
<h2>Lecturers</h2> <table> <tr> <th>ID</th> <th>Name</th> <th>Email</th> <th>Action</th> </tr> <tr *ngFor="let lecturer of lecturers"> <td>{{ lecturer.id }}</td> <td>{{ lecturer.name }}</td> <td>{{ lecturer.email }}</td> <td> <button (click)="updateLecturer(lecturer)">Edit</button> </td> </tr> </table>
组件类(lecturers.component.ts)
import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router } from '@angular/router'; @Component({ selector: 'app-lecturers', templateUrl: './lecturers.component.html', styleUrls: ['./lecturers.component.css'] }) export class LecturersComponent implements OnInit { lecturers: any[] = []; constructor(private http: HttpClient, private router: Router) { } ngOnInit(): void { this.fetchLecturers(); } fetchLecturers(): void { this.http.get<any[]>('http://localhost:8081/lecturers').subscribe( data => { this.lecturers = data; }, error => { console.error(error); } ); } updateLecturer(lecturer: any) { // Redirect to edit page with lecturer id in URL this.router.navigate(['/lecturers/edit', lecturer.id]); } }
服务端(SpringBoot)代码
讲师控制器(LecturerController.java)
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.CrossOrigin; import javax.validation.Valid; import java.util.List; @CrossOrigin(origins = "http://localhost:4200") @RestController @RequestMapping("/lecturers") public class LecturerController { private final LecturerService lecturerService; public LecturerController(LecturerService lecturerService) { this.lecturerService = lecturerService; } @GetMapping public List<Lecturer> getAllLecturers() { return lecturerService.getAllLecturers(); } // Create a new lecturer @PostMapping public Lecturer createLecturer(@Valid @RequestBody Lecturer lecturer) { return lecturerService.createLecturer(lecturer); } // Update an existing lecturer @PutMapping("/{id}") public Lecturer updateLecturer(@PathVariable Long id, @Valid @RequestBody Lecturer lecturer) throws NotFoundException { return lecturerService.updateLecturer(id, lecturer); } // Search for Lecturers by taxBand and salaryScale @GetMapping("/search") public ResponseEntity<List<Lecturer>> searchLecturersByTaxBandAndSalaryScale(@RequestParam("taxBand") String taxBand, @RequestParam("salaryScale") int salaryScale) { List<Lecturer> lecturers = lecturerService.searchLecturersByTaxBandAndSalaryScale(taxBand, salaryScale); return ResponseEntity.ok(lecturers); } }
CORS配置类(CorsConfig.java)
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("/**").allowedOrigins("*"); } }
问题排查与修复方案
问题根源
当前代码同时使用了两种CORS配置方式:
- 控制器上的
@CrossOrigin(origins = "http://localhost:4200") - 全局
CorsConfig类的allowedOrigins("*")配置
混合配置会导致SpringBoot的CORS处理逻辑冲突,无法正确返回Access-Control-Allow-Origin头;同时全局配置仅设置了允许的源,缺少对请求方法、头信息的明确授权,部分复杂请求仍会被拦截。
修复步骤
方案一:统一使用全局CORS配置(推荐)
删除控制器上的@CrossOrigin注解,修改CorsConfig类补充完整规则:
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("/**") // 允许Angular所在的源 .allowedOrigins("http://localhost:4200") // 允许所有HTTP请求方法 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许所有请求头 .allowedHeaders("*") // 允许携带凭证(如Cookie) .allowCredentials(true); } }
方案二:仅使用控制器级别的CORS配置
删除全局的CorsConfig类,完善控制器上的@CrossOrigin配置:
@CrossOrigin(origins = "http://localhost:4200", allowedMethods = {"GET", "POST", "PUT", "DELETE", "OPTIONS"}, allowedHeaders = "*", allowCredentials = true) @RestController @RequestMapping("/lecturers") public class LecturerController { // ... 原有代码 }
验证修复
- 重启SpringBoot服务
- 刷新Angular页面,检查控制台是否仍有CORS错误
- 查看浏览器网络请求的响应头,确认存在
Access-Control-Allow-Origin: http://localhost:4200
内容的提问来源于stack exchange,提问作者Keemo
相关产品推荐
相关产品推荐

