我正在尝试通过下面显示的WebMvcConfigurerAdapter
全局配置CORS。测试我通过我创建的小节点应用程序来模拟外部服务。当我尝试这种方法时,响应不包含正确的标题,并且
XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.
Global Config
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/query/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowCredentials(true);
}
}
然而,当我使用@CrossOrigin
注释时,它可以很好地响应正确的标题。
@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
......
}
可生产
Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333
我缺少使全局配置工作的原因(遵循此处的说明https://spring.io/blog/2015/06/08/cors-support-in-spring-framework)。我觉得我错过了一些简单的东西,因为注释控制器工作得很好。
答案 0 :(得分:14)
为了使全局CORS配置正常工作,客户端必须在OPTIONS请求中添加这两个标头。
Origin: http://host.com
Access-Control-Request-Method: POST
但是@CrossOrigin注释只需要“Origin”标题 您的客户端可能会添加“Origin”标头,但缺少“Access-Control-Request-Method”.....这就是为什么它适用于@CrossOrigin,但不适用于全局配置。
答案 1 :(得分:4)
你没有在它声明的方法,默认情况下只接受get方法。
试试registry.allowedMethods("*");
答案 2 :(得分:2)
在遇到此问题中记录的确切问题后,我能够使Spring Global CORS配置正常工作。我不得不做两件事:
allowedOrigins不能为*。这在Mozilla.org
从spring XML中删除mvc:annotation-driven。不能同时拥有XML配置和@EnableWebMvc。如果没有@EnableWebMvc,全局类将无法工作,因此必须删除mvc:annotation-driven。
答案 3 :(得分:1)
我遇到了类似的问题。我将WebMvcConfigurerAdapter更改为WebMvcConfigurationSupport,它开始工作。
除此之外,我还将xml配置文件中定义的RequestMappingHandlerMapping移动到java配置。
答案 4 :(得分:1)
我一直遇到完全相同的问题,该线程中的所有解决方案均无效。我已经设法解决以下问题:
一个新的配置bean:
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterConfiguration {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
对我的web.xml的修改,以为所有URL添加新的过滤器:
<filter>
<filter-name>corsFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>corsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
显然,您可以相应地修改cors配置。
答案 5 :(得分:1)
在Spring MVC应用程序(不是Spring Boot)上工作时,我遇到了同样的问题。 解决问题的唯一方法是在spring安全过滤器链中显式添加一个cors过滤器:
public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
final FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", corsFilter());
corsFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
}
protected CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowedOrigins(Arrays.asList(CrossOrigin.DEFAULT_ORIGINS));
config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
config.setAllowedHeaders(Arrays.asList(CrossOrigin.DEFAULT_ALLOWED_HEADERS));
config.setAllowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS);
config.setMaxAge(CrossOrigin.DEFAULT_MAX_AGE);
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
好运!
答案 6 :(得分:0)
我认为您的映射定义缺少*
:
registry.addMapping("/api/query/**")
如果没有额外的*
,此配置不会映射到/api/query/1121
请求路径(但它可以在/api/query/5
上运行。)
答案 7 :(得分:0)
我有一个类似的问题,而且似乎没有一种方法可行(除了对每个控制器使用@CrossOrigin
注释)。我在上面的Bharat Singh's解决方案中以及在对Spring Framework内部进行一些调试之后,遵循了以下解决方法-这是对我有用的方法( Spring Boot 2.0.6 + Spring Framework 5.0.10 ):
@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
/* (non-Javadoc)
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
*/
@Override
protected void addCorsMappings(CorsRegistry registry) {
//NOTE: servlet context set in "application.properties" is "/api" and request like "/api/session/login" resolves here to "/session/login"!
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedOrigins("*")
.allowedHeaders("*")
.allowCredentials(false);
}
}
最初,当我使用"/api/**"
映射时,它是在Spring内配置的,但是由于应用程序是通过"/api"
上下文部署的,因此类似"/api/session/login"
的请求在内部被映射到"/session/login"
,并且未在CORS配置中找到此类映射-请注意这一点!
答案 8 :(得分:0)
我遇到了同样的问题,设置了 maxAge 属性后,一切开始正常!
@Bean
public WebMvcConfigurer CORSConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedHeaders("*")
.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
.maxAge(-1) // add maxAge
.allowCredentials(false);
}
};
}
如果您选中 CrossOrigin 批注,则该批注具有分配给该属性的默认值
/**
* <p>By default this is set to {@code 1800} seconds (30 minutes).
*/
long maxAge() default -1;
答案 9 :(得分:0)
我正尝试通过WebMvcConfigurerAdapter全局配置CORS,并与日志一起显示。 而且我发现了日志消息,但出现了类似的错误
从源“某个源”对“ myurl”处的XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:没有“ Access-Controll-Allow-Origin”标头在请求的资源。
我的案例也擅长@CrossOrigin,但在全局配置中却不行。 希望对您有所帮助。
原因是web.xml。
1。
我有
2。
我删除了
有效。