No access-control-allow-origin header is present on the requested resource spring boot angular

I am new using Angular with SpringBoot, in my project I add the @CrossOrigin tag to avoid the CORS blocking in the project execution, but I keep getting the same error.

Error: Access to XMLHttpRequest at ' http://localhost:8080/springboot-crud-rest/api/v1/employees ' from origin ' http://localhost:4200 ' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

No access-control-allow-origin header is present on the requested resource spring boot angular

... import com.exception.ResourceNotFoundException; import com.model.Employee; import com.repository.EmployeeRepository; @CrossOrigin(origins="http://localhost:4200") @RestController @RequestMapping("/api/v1") public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; @GetMapping("/employees") public List<Employee> getAllEmployees(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { return employeeRepository.findAll(); } @GetMapping("/employees/{id}") public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); return ResponseEntity.ok().body(employee); } @PostMapping("/employees") public Employee createEmployee(@Valid @RequestBody Employee employee) { return employeeRepository.save(employee); } ...

In the employee.service.ts file of my Angular project I add the path to my SpringBoot project.

import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class EmployeeService { private baseUrl = 'http://localhost:8080/springboot-crud-rest/api/v1/employees'; constructor(private http: HttpClient) { } getEmployee(id: number): Observable<any> { return this.http.get(`${this.baseUrl}/${id}`); } createEmployee(employee: Object): Observable<Object> { return this.http.post(`${this.baseUrl}`, employee); } updateEmployee(id: number, value: any): Observable<Object> { return this.http.put(`${this.baseUrl}/${id}`, value); } deleteEmployee(id: number): Observable<any> { return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' }); } getEmployeesList(): Observable<any> { return this.http.get(`${this.baseUrl}`); } }

An Angular app is served by a different host than a Spring Boot API, so reaching for data via REST API will result in the following error:
"Failed to load http://localhost:8080/api: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access."

Read this post to learn how to configure Cross-origin resource sharing (CORS) to enable the cross-domain communication on a development environment.

For security reasons, browsers don’t allow calls to resources residing outside the current origin. To specify what kind of cross-domain requests are authorised in our app, we are going to configure CORS globally.

Allow Angular to consume data fetched by Spring Boot

In this example we are working on a project that is built with Maven into a single application with frontend powered by Angular and backend run with Spring Boot. Therefore, we require CORS only on the development environment, to enable working on an Angular app without the need of rebuilding the whole project.

You can find the spring-boot-angular-scaffolding project repository on GitHub.

Add the DevCorsConfiguration class to your config directory:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// spring-boot-angular-scaffolding/backend/src/main/java/in/keepgrowing/springbootangularscaffolding/config/DevCorsConfiguration.java

packagein.keepgrowing.springbootangularscaffolding.config;

import org.springframework.context.annotation.Configuration;

importorg.springframework.context.annotation.Profile;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

@Profile("development")

publicclassDevCorsConfiguration implementsWebMvcConfigurer{

    @Override

    publicvoidaddCorsMappings(CorsRegistry registry){

        registry.addMapping("/api/**").allowedMethods("GET", "POST","PUT","PATCH","DELETE","OPTIONS");

    }

}

This configuration enables CORS requests from any origin to the api/ endpoint in the application. You can narrow the access by using the allowedOrigins, allowedMethods, allowedHeaders, exposedHeaders, maxAge or allowCredentials methods – check out the examples in this spring.io blog post.

Declare the active profile of your application

Spring provides a way to configure an application accordingly to various environments – it picks up the application configuration based on the active profile.

Our DevCorsConfiguration class uses @Profile annotation to load its configuration only on a development environment. We will specify the active profile in the application.properties file:

# application.properties

spring.profiles.active=development

The work done in this post is contained in the commit 405a4aa5bae96105af5581551c1e6341c3b7acbf.

Run the backend and frontend modules separately, then open your browser on http://localhost:4200/ , you should see this Angular start screen, without any errors in the console:

No access-control-allow-origin header is present on the requested resource spring boot angular

Troubleshooting

Thanks to the Stormbreaker’s comment I realised I should edit the post to add the following.

You didn’t specify OPTIONS in the allowed methods list

To obtain the communication options available for the target resource, a preflight request with the OPTIONS  method is sent. You can read about the details in the Preflighted requests in CORS and Functional overview chapters in the MDN web docs about CORS. Make sure that the  OPTIONS  method is allowed:

// spring-boot-angular-scaffolding/backend/src/main/java/in/keepgrowing/springbootangularscaffolding/config/DevCorsConfiguration.java

.allowedMethods("GET","POST","PUT","PATCH","DELETE", "OPTIONS");

I missed that in the original version of my project, you can find the update in the 817bbe2acea969b1f686f2d721490d75ffef1631 commit.

You want to authorise users

When your project uses authentication and authorisation mechanisms, like Json Web Token standard, you should configure it to process authorisation header. Add "Authorisation"  to the exposedHeaders()  method like in the example below (line 17):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

// scrum_ally/backend/src/main/java/in/keepgrowing/springbootangularscaffolding/config/DevCorsConfiguration.java

packagein.keepgrowing.scrumally.config;

import org.springframework.context.annotation.Configuration;

importorg.springframework.context.annotation.Profile;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

@Profile("development")

publicclassDevCorsConfiguration implementsWebMvcConfigurer{

    @Override

    publicvoidaddCorsMappings(CorsRegistry registry){

        registry.addMapping("/api/**")

                .allowedMethods("GET","POST","PUT","PATCH","DELETE","OPTIONS")

                .exposedHeaders("Authorization");

    }

}

I was able to solve this problem thanks to this response from StackOverflow. You can find this code in my scrum_ally repository.

Photo by Daria Shevtsova on StockSnap