I am trying to enable CORS in my Spring Boot app, but it is not working at all.
I have tried
@CrossOrigin
annotationI 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.
Enable CORS in Controller Method We need to set the origins for RESTful web service by using @CrossOrigin annotation for the controller method. This @CrossOrigin annotation supports specific REST API, and not for the entire application.
If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.
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 });
}
You need add origins for the annotation @CrossOrigin(origins = "*")
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