I am working on a frontend application in React that connects to a middleware service written in Spring boot. I am attempting to call an endpoint from the front end as follows:
return axios.post('http://localhost:8085/workshop/client/createClient', {username})
.then((response) => {
console.log('Success')
})
.catch((error) => console.log(error));
Whenever I make the request in my browser I get the following errors:
OPTIONS http://localhost:8085/workshop/client/createClient 401 ()
Failed to load http://localhost:8085/workshop/client/createClient: Response for preflight has invalid HTTP status code 401.
As far as I understand, this is because the preflight request is being blocked by my middleware application. Having read a bit online about enabling this, I have added a CorsFilter to my spring boot application:
@Slf4j
public class CORSFilter implements Filter {
private static final String ONE_HOUR = "3600";
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", ONE_HOUR);
response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept, x-device-user-agent, Content-Type");
if (req instanceof HttpServletRequest) {
HttpServletRequest httpServletRequest = (HttpServletRequest) req;
if (httpServletRequest.getHeader(HttpHeaders.ORIGIN) != null
&& httpServletRequest.getMethod().equals(HttpMethod.OPTIONS.name())
&& httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null) {
log.debug("Received an OPTIONS pre-flight request.");
return;
}
}
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
}
And
@Configuration
public class MvcConfiguration {
@Bean
public FilterRegistrationBean corsFilter() {
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
filterRegistrationBean.setFilter(new CORSFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.setOrder(0);
return filterRegistrationBean;
}
}
Here is an example of the endpoint:
@PostMapping("/createClient")
public ResponseEntity<?> createClient(@RequestBody CreateClientDto clientDto) {
try {
...
return new ResponseEntity<>(responseBody, OK);
} catch (Exception e ...) {}
}
Any help would be greatly appreciated :)
Update: I had the url slightly wrong for the request (hence the 404). I have updated the error message. I still seem to be having CORS issues.
These are the response headers that I can see in the dev tools:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:access-control-allow-credentials, access-control-allow-methods, access-control-allow-origin, allow, content-type
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:3000
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Thu, 01 Mar 2018 14:06:38 GMT
Expires:0
Pragma:no-cache
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
Vary:Origin
WWW-Authenticate:Basic realm="Spring"
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
And the request headers:
OPTIONS /workshop/client/createClient HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3)
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,allow,content-type
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7
So you have to navigate to the controller in Spring boot java and allow the URL of Reactjs to be given the permission for accessibility in the server (Spring boot). This will help you get rid of the CORS issue.
One of the work around is to add a “proxy” property to your package. json file and assign your service base url to it. Thus, any request made on your react app will be proxied to http://localhost:8080/api/* or https:my-service.com/api/*, as against your React client origin via http://localhost:3000/api/*.
Configure CORS for Spring Bootjava and add a @CrossOrigin annotation to enable cross-origin resource sharing (CORS) from the client ( http://localhost:3000 ). After making these changes, restart the server, refresh your browser, and you should be able to see a list of beers from your Spring Boot API.
I also had this issue, but allow me to give a straight forward answer in a simpler communication manner.
First and foremost, you have to tell your server (Spring boot java), about the client (Reactjs ) URL.
For example, most of the times spring boot uses http://localhost:8080
and Reactjs uses http://localhost:3000
.
So you have to navigate to the controller in Spring boot java and allow the URL of Reactjs to be given the permission for accessibility in the server (Spring boot). This will help you get rid of the CORS issue.
How do we do this in Spring boot? simply we add the @CrossOrigin
annotation specifying the Reactjs URL link as below:
For example :
@GetMapping("/orphans")
@CrossOrigin(origins = "http://localhost:3000")
Iterable<Student> read() {
return studentService.findAll();
}
The method above is to list all the orphans, so I gave Reactjs URL link permission then I got rid of the CORS issue.
Happy coding.
Refer to the below sample code to resolve this issue.
@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(value="/sample", method = RequestMethod.GET, produces = "application/json")
public Student getStudent(){
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With