nginx解决跨域比较简单,在location中增加跨域头就可以解决
# 静态资源转发
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Max-Age 1728000;
root /home/www/cdn;
}
有时候是没有nginx的场景,需要在tomcat层解决,网络经常给的配置方案是在web.xml中添加CrosFilter来解决。
<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,DELETE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在实际使用过程中,前台的ajax请求,会出现preflight预检场景未通过报403问题。
场景1:接口请求未使用withCredentials时,对跨域要求不高,增加跨域头可以解决
Access-Control-Allow-Origin:*
cors.allowed.methods:GET,POST,HEAD,OPTIONS
场景2:ajax接口请求使用了withCredentials时,由于涉及敏感信息的传递,对跨域的要求更高,其中Access-Control-Allow-Methods 不允许配置*,需要配置指定的发起请求的地址(Origin)
Access-Control-Allow-Methods://具体请求地址,不能够使用*模糊匹配
Access-Control-Allow-Credential:true ,必须要开启
最后踩坑点:
1、OPTIONS请求报403,原因是tomcat web.xml中禁用了OPTIONS请求
2、tomcat 通过web.xml配置CrosFilter过滤器增加这几个头,但实际没生效(理论上是可以的),最后改用了springboot的@Configuration实现corsFilter
@Configuration
public class CorsConfig {
// 当前跨域请求最大有效时长。这里默认1天
private static final long MAX_AGE = 24 * 60 * 60;
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("http://10.10.11.1:8080"); // 1 设置访问源地址,或者http://localhost:7060
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法,或设置为"GET", "POST", "DELETE", "PUT"
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setMaxAge(MAX_AGE);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
如何发现问题,Chrome浏览器F12查看接口报preflight报错,此时没有具体的信息,可以打开Console查看,会打印出相关的详细报错:没有请求头Access-Control-Allow-Origin;请求头不允许使用模糊匹配*;必须开启Credential。