๐ด The Error You're Seeing
Confirm this matches your console output. If it does, you're in the right place.
Access to XMLHttpRequest at 'http://localhost:8080/api/users' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Zone.js:2845 Cross-Origin Read Blocking (CORB) blocked cross-origin response with MIME type application/json.โก Quick Fix Works 80% of the time
Add the @CrossOrigin annotation to your controller class.
@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class UserController { ... }๐ ๏ธ Solutions (3 Ways to Fix)
Add @CrossOrigin to Controller
๐ Use this for a quick fix on a single controller.
This annotation tells Spring to include the Access-Control-Allow-Origin header in the response for this specific controller.
@RestController
@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping("/api")
public class UserController { ... }Configure Global CORS in WebMvcConfigurer
๐ Use this when you have many controllers and want a single global configuration.
Define a WebMvcConfigurer bean that maps CORS rules for all URL paths.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "PUT", "DELETE");
}
}Configure CORS in Spring Security 6
๐ Use this if you are using Spring Security, as it blocks CORS before your controllers.
Spring Security intercepts requests before MVC. You must enable CORS in your SecurityFilterChain and provide a CorsConfigurationSource bean.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.cors(cors -> cors.configurationSource(corsConfigurationSource()));
// ...
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(List.of("http://localhost:4200"));
config.setAllowedMethods(List.of("GET", "POST", "PUT", "DELETE"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
return source;
}๐ Version Notes
CORS configured via WebMvcConfigurer or @CrossOrigin.
If Spring Security is present, CORS MUST be configured in SecurityFilterChain using http.cors(). WebMvcConfigurer alone is ignored.
๐ง Why this Happens
Tap to expand the deep technical explanation
Browsers enforce the Same-Origin Policy for security. If your Angular app (port 4200) tries to make an AJAX request to your Spring Boot API (port 8080), the browser blocks it unless Spring Boot explicitly sends an Access-Control-Allow-Origin header saying 'I allow requests from port 4200'.
The HITEC City Parking Spot Analogy:
It's like a bouncer at a club. If you aren't on the VIP list (allowed origins), the bouncer (browser) won't let you in, even if the club (API) is open.
๐ก๏ธ How to Prevent This Next Time
Always set up global CORS configuration early in your project setup, before writing any controllers.