I have a React application running locally consuming services of a SpringBoot application on development environment. On React we have a proxy server to change the origin from "localhost" to the development domain name "dev-web".
proxyServer.js
switch (TARGET) {
....
default:
target_url = "https://dev-web.com";
break;
}
...
module.exports = {
...
historyApiFallback: true,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
},
proxy: {
"/api/*": {
changeOrigin: true,
cookieDomainRewrite: "localhost",
logLevel: "debug",
target: `${target_url}`,
onProxyReq: (proxyReq) => {
if (proxyReq.getHeader("origin")) {
proxyReq.setHeader("origin", `${target_url}`);
}
},
secure: false,
pathRewrite: {
"^/api": "",
},
},
...
The problem is that when I try to make a GET request everything works, but when I try to make a POST request, it gives an error because before post, browser tries to make a OPTIONS request on preflight.
How can I solve this problem without put my server addres on spring annotation on controller:
Controller.java
@CrossOrigin(origins = "http://localhost:8233/", maxAge = 3600)
@RestController
@RequestMapping("/access-type")
@Validated
public class AccessTypeController {
Why the error occurs only on OPTIONS method?
CodePudding user response:
in your .htaccess
:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header set Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
and if needed
Header add Access-Control-Allow-Credentials "true"
Don't forget to activate the apache module headers a2enmod headers
CodePudding user response:
You need to specify what to do with CORS, which is what you've done with @CrossOrigin
. There's no way out of this (other than setting a wildcard like *
)
You can inject an application variable with the host name, however then you need to do the same with every controller. It's easier to set a CORS config bean
On recent versions of Spring Boot, you can create a CorsConfigurationBean
like this (in any @Configuration
annotated class`:
/**
* specify CORS to work from SPA UI
*/
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOriginPatterns(List.of("http://localhost:300*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
Read the docs for deatils of this specific config (ie allow credentials is to send headers that mean the browser will send cookies ) Spring CORS Docs
Its pretty simple to set the allowed origin in the application.properties file and you can use profiles to set it for the relevant environment.
I dont think the proxy should affect anything, however I would remove the CORS headers from that configuration (Access-Allow-*
) as it will only serve to confuse what's happening between the server and the client.