通常我们在跨域是会提示如下错误:
Access to XMLHttpRequest at 'http://192.168.09.113:9003/dispatch/export'
from origin 'http://10.2.8.79' has been blocked by CORS policy: No 'Access-Control-Allow-Origin'
header is present on the requested resource.
那我我们该如何解决这个问题啦,网上提供后台常用的三种方法:
首先了解下跨域请求参数设置
Access-Control-Allow-Origin:支持哪些来源的请求跨域。
Access-Control-Allow-Methods:支持哪些方法跨域。
Access-Control-Allow-Credentials:跨域请求默认不包含cookie,设置为true可以包含cookie。
Access-Control-Expose-Headers:跨域请求暴露的字段。
CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
Access-Control-Max-Age:表明该响应的有效时间为多少秒。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。
转载至:https://blog.csdn.net/zhangleiyes123/article/details/101382749
1、重写WebMvcConfigurer的addCorsMappings方法,解决跨域问题
/**
* 解决跨域
*/
@Configuration
public class CorsFilter implements WebMvcConfigurer{
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedHeaders()
//允许使用的请求方法,以逗号隔开
.allowedMethods("*")
//表示接受任意域名请求
.allowedOrigins("*")
//表示是否允许发送Cookie。默认情况下Cookie不包括在CORS请求中。当设为true时表示服务器明确许可,Cookie可以包含在请求中一起发送给服务器。
.allowCredentials(true)
//缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数
.maxAge(3600);
}
}
2、重写 Filter(过滤器)中doFilter方法
/**
* 使用Filter解决跨域
*/
@Component
public class CorsFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
//该字段必填。它的值要么是请求时Origin字段的具体值,要么是一个*,表示接受任意域名的请求。
response.setHeader("Access-Control-Allow-Origin", "*");
//该字段必填。它的值是逗号分隔的一个具体的字符串或者*,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。
response.setHeader("Access-Control-Allow-Methods", "*");
//该字段可选,用来指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求。
//response.setHeader("Access-Control-Max-Age", "3600");
//该字段可选。它的值是一个布尔值,表示是否允许发送Cookie.默认情况下,不发生Cookie,即:false。对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json,这个值只能设为true。如果服务器不要浏览器发送Cookie,删除该字段即可。
//response.setHeader("Access-Control-Allow-Credentials", "true");
//该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
3、在导出的头部配置如下设置
HttpServletResponse response = (HttpServletResponse) servletResponse;
//设置允许所有来源都可以跨域
response.setHeader("Access-Control-Allow-Origin", "*");
//设置允许跨域的请求方式post,get,put,*代表所有请求方式
response.setHeader("Access-Control-Allow-Methods", "*");
//该字段可选,用来指定本次预检请求的有效期,单位为秒。在有效期间,不用发出另一条预检请求。
//response.setHeader("Access-Control-Max-Age", "3600");
4、利用nginx解决跨域问题
此时统一通过nginx访问前后端项,通过/resource标识转发到后端项目。浏览器同源策略记录的就是http://192.168.137.189:8080/
,浏览器也只访问这个nginx的8080地址,跨域问题也就得到了解决。
server
{
listen 8080;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
location /resource {
rewrite ^/resource/?(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.137.189:8082/; # 转发地址
}
}
5、网关配置允许跨域请求
@Configuration
public class GulimallCorsConfiguration {
/**
* 功能描述:网关统一配置允许跨域
*
* @author cakin
* @date 2020/10/25
* @return CorsWebFilter 跨域配置过滤器
*/
@Bean
public CorsWebFilter corsWebFilter(){
// 跨域配置源
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
// 跨域配置
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 1 配置跨域
// 允许所有头进行跨域
corsConfiguration.addAllowedHeader("*");
// 允许所有请求方式进行跨域
corsConfiguration.addAllowedMethod("*");
// 允许所有请求来源进行跨域
corsConfiguration.addAllowedOrigin("*");
// 允许携带cookie进行跨域
corsConfiguration.setAllowCredentials(true);
// 2 任意路径都允许第1步配置的跨域
source.registerCorsConfiguration("/**",corsConfiguration);
return new CorsWebFilter(source);
}
}