Reputation: 298
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.
Upvotes: 3
Views: 3412
Reputation: 298
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");
}
}
Upvotes: 3
Reputation: 1416
In your configuration file if you are using WebMvcConfigurer
base package you should override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
Upvotes: 1