可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am getting the following problem after porting web.xml to java config
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
Based on a few Spring references, the following attempt has been tried:
@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
@Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
"Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}
The values chosen were taken from a working web.xml filter:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param> </filter> <filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Any ideas why the Spring java config approach is not working like the web.xml file did?
回答1:
Change the CorsMapping from registry.addMapping("/*")
to registry.addMapping("/**")
in addCorsMappings
method.
Check out this Spring CORS Documentation .
From the documentation -
Enabling CORS for the whole application is as simple as:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
You can easily change any properties, as well as only apply this CORS configuration to a specific path pattern:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}
Controller method CORS configuration
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
}
To enable CORS for the whole controller -
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
You can even use both controller-level and method-level CORS configurations; Spring will then combine attributes from both annotations to create merged CORS configuration.
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin("http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
回答2:
We had the same issue and we resolved it using Spring's XML configuration as below:
Add this in your context xml file
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>
回答3:
Helpful tip - if you're using Spring data rest you need a different approach.
@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.getCorsRegistry().addMapping("/**")
.allowedOrigins("http://localhost:9000");
}
}
回答4:
If you are using Spring Security ver >= 4.2 you can use Spring Security's native support instead of including Apache's:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
The example above was copied from a Spring blog post in which you also can find information about how to configure CORS on a controller, specific controller methods, etc. Moreover, there is also XML configuration examples as well as Spring Boot integration.
回答5:
Following on Omar's answer, I created a new class file in my REST API project called WebConfig.java
with this configuration:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}
This allows any origin to access the API and applies it to all controllers in the Spring project.
回答6:
Omkar's answer is quite comprehensive.
But some part of the Global config part has changed.
According to the spring boot 2.0.2.RELEASE reference
As of version 4.2, Spring MVC supports CORS. Using controller method
CORS configuration with @CrossOrigin annotations in your Spring Boot
application does not require any specific configuration. Global CORS
configuration can be defined by registering a WebMvcConfigurer bean
with a customized addCorsMappings(CorsRegistry) method, as shown in
the following example:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
Most answer in this post using WebMvcConfigurerAdapter
, however
The type WebMvcConfigurerAdapter is deprecated
Since Spring 5 you just need to implement the interface
WebMvcConfigurer:
public class MvcConfig implements WebMvcConfigurer {
This is because Java 8 introduced default methods on interfaces which
cover the functionality of the WebMvcConfigurerAdapter class
回答7:
I also had messages like No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
I had configured cors properly, but what was missing in webflux in RouterFuncion was accept and contenttype headers APPLICATION_JSON like in this piece of code:
@Bean
RouterFunction<ServerResponse> routes() {
return route(POST("/create")
.and(accept(APPLICATION_JSON))
.and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}