简体   繁体   中英

CORS in spring boot is not working - getting empty response

I am using Spring Boot (Tomcat + Java) for my backend app and React for my front end. I am trying to access " http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03 " from " http://localhost:3000 ".

I added @CrossOrigin(origins = "*") both at the controller level and at endpoint level. I am getting empty result. I added @CrossOrigin both at the controller level and at endpoint level. I am getting empty result.

If I remove the @CrossOrigin annotation, I am getting the Cors error. That means the annotation is necessary. The error is "Access to fetch at ' http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03 ' from origin ' http://localhost:3000 ' 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."

If I copy paste the link in the browser directly, it is working and returns JSON. If I call " https://cdn.rawgit.com/rrag/react-stockcharts/master/docs/data/MSFT.tsv " it is also returning result.

To avoid typos, I did console.log and I am pasting these from console.log.

I am using fetch for 'get'ting.

[Edit 1] I am looking at the tomcat logs and will update it shortly.

[Edit 2] TL;DR It's not a CORS problem.

Full description: 1. The response for " http://localhost:8080/vr-backend-0.0.1-SNAPSHOT/stockdata/NIFTY19DECFUT?from=2019-12-03&to=2019-12-03 " was 200.

  1. I logged in the spring boot app and looked at the tomcat logs. It reaches the controller method and I get the proper results from DB. When I send the response back, I am getting empty result in the browser. As mentioned before, if I hit the url directly, I am getting proper results.

  2. It is not a preflight OPTIONS request.

  3. So it can be concluded that it is not a CORS problem. @CrossOrigin annotation works

I looked at the logs after posting the question. So this question can be closed as it is incorrect. If I am not able to fix the empty response problem, I will post a separate question as this question title is misleading.

Thank you all for the response.

I am using it in this way to allow requests from all origins. It is working for me for all of my projects.

package com.example.demo.filters;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

@Component
public class CORSFilter extends OncePerRequestFilter {

    @Override
    public void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
            final FilterChain filterChain) throws ServletException, IOException {

        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS,
                "Origin, Content-Type, Accept, Authorization, Accept-Language, connection, Cache-Control, Access-Control-Request-Method, Access-Control-Request-Headers");
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD");
        response.setHeader(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,
                "Access-Control-Allow-Origin, Access-Control-Allow-Credentials");
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, request.getHeader(HttpHeaders.ORIGIN));
        filterChain.doFilter(request, response);

    }
}

I've only ever configured CORS at the application level, but the documentation for the @CrossOrigin annotation says that it allows all origins by default, so you might want to try @CrossOrigin() instead of @CrossOrigin(origins = "*")

The documentation also says that it supports "the HTTP methods specified in the @RequestMapping annotation", so you may need to add the OPTIONS method in addition to GET or POST, or whatever method you are currently using (CORS requires support for the OPTIONS method).

You can just make use of @CrossOrigin in your api endpoint and not mention origin.

Specifying origin may cause impacts on multiple layers of environments too.

Keep in mind Access-Control-Allow-Origin: * is only used if you don't have any authentication method (requests without credentials). See:

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin

If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled

Don't use 'no-cors' in your fetch call, because you'll get opaque responses. Either specify 'cors' or don't specify anything.

const response = await fetch("http://localhost:8080", {
   method: 'GET',
   // mode: 'cors',
   headers: {
      'Accept': 'application/json'
   }
});

Actually, when you get that 200 OK but opaque response it's not a problem from the server anymore. The response is 200, but the data is opaque because the frontend is probably setting 'no-cors' or similar. See:

https://developers.google.com/web/updates/2015/03/introduction-to-fetch

Regarding the backend, in Spring Boot (w/Kotlin) I'm using this to send Access-Control-Allow-Origin: * header, based on spring-boot-starter-security library.

package demo.config

import org.springframework.context.annotation.Configuration
import org.springframework.security.config.annotation.web.builders.HttpSecurity
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter

@Configuration
class GeneralApiSecurityConfig() : WebSecurityConfigurerAdapter() {
    override fun configure(http: HttpSecurity) {
        http.cors()
    }
}

Just http.cors()

Oh, and it may be a piece of trivial advice but if you are messing with configurations, do restart your server each time, otherwise, chances are you are refreshing the frontend client but the server is stuck with previous attempts.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM