3

How to fix CORS error in my React and spring application.

I've implemented a simple method to get list of users. I've tested this endpoint using postman. Now I'm fetching this list from my react js application using fetch API. I've added the @CrossOrigin annotation in my spring backend. I've also added a proxy to my package.json file in my React application.

React JS code :-

import React from 'react';
import { Component } from 'react';

class DropDownUsers extends Component {
  state = {
    users : [],
    selectedUser : "",
    validationError : ""
  }

  componentDidMount() {

   fetch("http://localhost:8080/api/users")
    .then(data => {
      let usersFromApi = data.map(user => {
        return {
          value : user,
          display : user
        }})
      this.setState({ users : [{value: '', display: '(Choose the user)'}].concat(usersFromApi)});
    })
      .then((response) => {
        return response.json();
      })
      .catch(error => {
        console.log(error);
      });
  }

  render() {
    return (
      <div>
        <select value={this.state.selectedUser}
                onChange={(e) => this.setState({selectedUser: e.target.value})}
         >
         {this.state.users.map((user) => <option key={user.value} value={user.value}> {user.display}</option>)}
        </select>
        <div style={{color:'red',marginTop:'5px'}}>
          {this.state.validationError}
        </div>
      </div>
    )
  }
}

export default DropDownUsers;

Error message :-

Access to fetch at 'http://localhost:8080/api/users' from origin 'http://localhost:3001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled

Spring Config file :-

public ConfigurableServletWebServerFactory servletContainer() {
        final TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();

        if (ajpEnabled) {
            factory.setProtocol("AJP/1.3");

            factory.addConnectorCustomizers(connector -> {
                connector.setSecure(false);
                connector.setScheme("http");
                connector.setAllowTrace(true);
                connector.setPort(8009);
            });
        }

        return factory;
    }

Spring Controller :-

@Slf4j
@EnableLogging
@CrossOrigin(origins = "http://localhost:3001")
@Path("/users")
public class ListOfUsers {

    @Autowired
    DAO DAO;

    @GET
    @Produces(APPLICATION_JSON)
    public Response execute(@Valid ListOfUsersBean listOfUsersBean) {

        final Optional<List<ListOfUsersBean>> user = DAO.getTotalListOfUsers();
        return status(SC_OK).entity(user).build();
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("*");
            }
        };
    }

}

I want to list the users in a dropdown menu. Any help would be appreciated.

11
  • Dod you restart the Spring application? Commented Oct 3, 2019 at 6:26
  • 1
    @MatthewGaiser I did restart. Commented Oct 3, 2019 at 6:27
  • What's the error you get? In postman, do you see the cors headers in the response? Commented Oct 3, 2019 at 6:29
  • @acdcjunior I did not see the cors headers in the response. Error message :- Access to fetch at 'http://localhost:8080/api/users' from origin 'http://localhost:3001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled Commented Oct 3, 2019 at 6:36
  • Do you see the Access-Control-Allow-Origin header in the response received by postman? Commented Oct 3, 2019 at 6:37

2 Answers 2

3

I was able to solve the problem. I had to add a CORSFilter class as follows that I found in this page :- https://stackoverflow.com/questions/23450494/how-to-enable-cross-domain-requests-on-jax-rs-web-services :-

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(final ContainerRequestContext requestContext,
                       final ContainerResponseContext cres) throws IOException {
        cres.getHeaders().add("Access-Control-Allow-Origin", "*");
        cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
        cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
        cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        cres.getHeaders().add("Access-Control-Max-Age", "1209600");
    }

}
Sign up to request clarification or add additional context in comments.

Comments

1

In your configuration file if you are using WebMvcConfigurer base package you should override

    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }

1 Comment

I've added the config file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.