22

I am trying to enable CORS in my Spring Boot app, but it is not working at all.


I have tried

I have no clue how to fix this at this point in time, nor what the issue is with CORS not working.


My code

Controller

@RestController
public class DbController {

    @Autowired
    private IDAO conn;

    @CrossOrigin
    @GetMapping("/foo")
    public List<Foo> getFoo() {
        return conn.getFooFromDao();
    }
}

DAO

    @Repository
    public class DaoImpl implements IDAO {

    @Autowired
    private JdbcTemplate temp;

    public List<Foo> getFooFromDao() {

        List<Foo> data = new ArrayList<>();

        String sql = "SELECT fooName FROM BigFoo ORDER BY fooName ASC;";

        data.addAll(temp.query(sql, new BeanPropertyRowMapper(BigFoo.class)));
        return data;
    }
}

Expected:

I want my controller to be accessible from any origin/domain with any method.

Actual:

My controller is not accessible from any origin/domain. It gives my Angular frontend an error:

EDIT: My error in the frontend

Access to XMLHttpRequest at 'localhost:8080/foo' from origin 'http://localhost:4200' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

Second edit:

This is my code in Angular (frontend):

Service

getFoo() {
    return this.http.get("localhost:8080/foo");
  }

I am using HttpClient from import { HttpClient } from "@angular/common/http";

I also verified that the URL works in that service method by copy & pasting it into my browser. It does indeed, return JSON, which omits the possibility of a wrong URL or a typo.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Compiler v2
  • 3,509
  • 10
  • 31
  • 55
  • I'm sorry, I don't understand what you are saying. What do you mean Spring In Action 5? – Compiler v2 Jul 08 '19 at 01:27
  • Do you get any signal in your spring tomcat console, I mean did the request reach it? and also show me how are you consuming the service? till now you're doing it correctly. – Mohamed Sweelam Jul 08 '19 at 01:42
  • No, I am not getting any response in my spring console. It just gives me the error in my browser without responding that it hit it in my IntelliJ console. Also, what do you mean "*consuming the service*"? – Compiler v2 Jul 08 '19 at 01:51
  • I will update this also in my answer – Mohamed Sweelam Jul 08 '19 at 01:52
  • 3
    Typo; you need to do `this.http.get("http://localhost:8080/foo")` rather than `this.http.get("localhost:8080/foo")`. That is, you must include the `http://` part. – sideshowbarker Jul 08 '19 at 02:00
  • I already tried, it does not allow a secure connection. – Compiler v2 Jul 08 '19 at 02:05
  • Thank you for the link to the answer! It fixed my problem. – Compiler v2 Jul 08 '19 at 02:31
  • 2
    You need to type protocol name "http://" in front of your url in your Angular app: e.g. this.http.get("http:// localhost:8080/foo") – user1697575 Jul 08 '19 at 12:52
  • I know its late but, I agree with @user1697575, I was also facing the same issue but after looking at the error more carefully I added http with my request in angular code and it started working. – Jainesh kumar Aug 06 '20 at 17:05
  • https://stackoverflow.com/a/76845059/11085894 check this it might help you – Deepak Das Aug 06 '23 at 08:47

2 Answers2

17

Put your cross origin in the controller level itself

@RestController
@CrossOrigin(origins = "*")
public class DbController {

    @Autowired
    private IDAO conn;

    @GetMapping("/foo")
    public List<Foo> getFoo() {
        return conn.getFooFromDao();
    }
}

This is direct solution recommended by spring, you can also define a filter which will allow cross origin for all response

@Component
public class SimpleCORSFilter implements Filter {

private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);

public SimpleCORSFilter() {
    log.info("SimpleCORSFilter init");
}

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
    response.setHeader("Access-Control-Max-Age", "3600");
    response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");

    chain.doFilter(req, res);
}

  @Override
  public void init(FilterConfig filterConfig) {}

  @Override
  public void destroy() {}

}

Also you need to know, you didn’t mention the protocol http or https in your code snapshot, and you didn't also send a GET request yet, the request will be sent when you start subscribing on it like this

getFoo() {
    return this.http.get("http://localhost:8080/foo");
}

getFoo().subscribe(resp -> { // your logic });

// or directly inside getFoo() like this 
getFoo() {
    return this.http.get("http://localhost:8080/foo")
    .subscribe(resp -> { // your logic });
}
Mohamed Sweelam
  • 1,109
  • 8
  • 22
  • 3
    This did not work. – Compiler v2 Jul 08 '19 at 01:09
  • What are you getting, error message in front-end and stacktrace? – Mohamed Sweelam Jul 08 '19 at 01:17
  • I will post that into my question. – Compiler v2 Jul 08 '19 at 01:18
  • I have done that as well, still does not fix the issue. – Compiler v2 Jul 08 '19 at 01:28
  • I also updated the answer, I believe the issue is not from spring itself, check API URL is written correctly in font-end , or you can attach a snapshot also from UI code – Mohamed Sweelam Jul 08 '19 at 01:29
  • I will post it into my question. – Compiler v2 Jul 08 '19 at 01:30
  • @Compilerv2 I had the same error and the trick in my case was to add the `http://` before `localhost:4200/api`. It turned out not to be a Spring issue, but one from Angular. Try to see how the request in actually made in dev console in a browser and check the actual URL called. – bogdan.rusu Jun 08 '20 at 16:49
  • I am facing a similar issue exactly like this for almost 3 weeks. I have all my Controllers having ```@CrossOrigin(origins = arrayOf("*"),allowedHeaders = arrayOf("*"),methods = arrayOf(RequestMethod.OPTIONS,RequestMethod.GET,RequestMethod.POST,RequestMethod.DELETE,RequestMethod.PUT),maxAge = 3600L,allowCredentials = "true" )``` I also tried the CorsConfiguration and I can see them as filters but I still get the following error Access to XMLHttpRequest at 'https://namdev.xxx.com:8443/dts-login' from origin 'https://namdev.xxx.com' has been blocked by CORS policy – user1561783 Apr 24 '21 at 00:21
  • 1
    Essentially - the Spring's CORs interaction between angularApp <----> browser <---> backendApp does not work out of the box even with their own textbook Spring tutorials mentioned here and in other places. – user1561783 Apr 24 '21 at 00:23
  • For me solution from https://stackoverflow.com/questions/21696592/disable-spring-security-for-options-http-method worked. Had to add .antMatchers(HttpMethod.OPTIONS).permitAll() – Devashish Priyadarshi Feb 03 '22 at 09:56
  • after facing this problem i accept Angular have steep learning curve – harsha kumar Reddy Mar 09 '22 at 18:14
1

You need add origins for the annotation @CrossOrigin(origins = "*")

todaynowork
  • 976
  • 8
  • 12
  • 4
    That did not work for my controller method. – Compiler v2 Jul 08 '19 at 01:08
  • "My controller is not accessible from any origin/domain", so can you access from original domain, like localhost 8080 default of spring? please make sure your rest api is available before you access from cross domain. – todaynowork Jul 08 '19 at 01:18
  • 3
    Yes, it is working when I go to `localhost:8080/foo` in my browser. Funny bug isn't it? – Compiler v2 Jul 08 '19 at 01:21
  • from you code, you did not set the wild char "*", so you make sure you add `origins = "*"`, right? – todaynowork Jul 08 '19 at 01:23
  • @Compilerv2 i'm facing similar issue `local:8080` works but `localhost:3005` fails after adding cross origin thing too why??? – Ashish Kamble May 28 '21 at 11:41