Java 跨域问题的处理方式
问题
在页面上要使用Ajax请求去获取另外一个服务的数据,由于浏览器的同源策略,所以直接请求会得到一个Error。
Failedtoloadhttps://www.baidu.com/:No'Access-Control-Allow-Origin'headerispresentontherequestedresource.Origin'http://localhost:3000'isthereforenotallowedaccess.Ifanopaqueresponseservesyourneeds,settherequest'smodeto'no-cors'tofetchtheresourcewithCORSdisabled.
大概就是这样的一个错误,关键词是Access-Control-Allow-Origin,一般出现这个都是跨域问题。
解决方案
解决跨域问题的方式有很多,但这里之说Cors的方案。
在后台添加一个Filter过滤器
/**
*使用自定义的Filter拦截器实现跨域请求、
*适用于所有的JavaWeb项目并且不局限于某个框架
*注:此处的@Component仅为让Spring知道这个Bean,不然拦截器不会加载
*
*@authorrxliuli
*/
publicclassCustomCorsFilterConfigimplementsFilter{
@Override
publicvoidinit(FilterConfigfilterConfig){
}
@Override
publicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,FilterChainfilterChain)throwsIOException,ServletException{
//允许所有来源
StringallowOrigin="*";
//允许以下请求方法
StringallowMethods="GET,POST,PUT,DELETE,OPTIONS";
//允许以下请求头
StringallowHeaders="Content-Type,X-Token,Authorization";
//允许有认证信息(cookie)
StringallowCredentials="true";
Stringorigin=request.getHeader("Origin");
//此处是为了兼容需要认证信息(cookie)的时候不能设置为*的问题
response.setHeader("Access-Control-Allow-Origin",origin==null?allowOrigin:origin);
response.setHeader("Access-Control-Allow-Methods",allowMethods);
response.setHeader("Access-Control-Allow-Credentials",allowCredentials);
response.setHeader("Access-Control-Allow-Headers",allowHeaders);
//处理OPTIONS的请求
if("OPTIONS".equals(request.getMethod())){
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request,response);
}
@Override
publicvoiddestroy(){
}
}
在web.xml文件中添加拦截器配置(注:如果可能就配置成第一个Filter)
customCorsFilterConfig CustomCorsFilterConfig customCorsFilterConfig /*
SpringWeb的解决方案
配置一个每次请求都过滤一次的Filter就好了
@Configuration
publicclassCorsConfig{
@Bean
publicOncePerRequestFiltercorsFilter(){
returnnewOncePerRequestFilter(){
@Override
protectedvoiddoFilterInternal(HttpServletRequestrequest,HttpServletResponseresponse,FilterChainfilterChain)throwsServletException,IOException{
//允许所有来源
StringallowOrigin="*";
//允许以下请求方法
StringallowMethods="GET,POST,PUT,DELETE,OPTIONS";
//允许以下请求头
StringallowHeaders="Content-Type,X-Token,Authorization";
//允许有认证信息(cookie)
StringallowCredentials="true";
Stringorigin=request.getHeader("Origin");
//此处是为了兼容需要认证信息(cookie)的时候不能设置为*的问题
response.setHeader("Access-Control-Allow-Origin",origin==null?allowOrigin:origin);
response.setHeader("Access-Control-Allow-Methods",allowMethods);
response.setHeader("Access-Control-Allow-Credentials",allowCredentials);
response.setHeader("Access-Control-Allow-Headers",allowHeaders);
//处理OPTIONS的请求
if("OPTIONS".equals(request.getMethod())){
response.setStatus(HttpServletResponse.SC_OK);
return;
}
filterChain.doFilter(request,response);
}
};
}
}
使用示例
下面是一些简单的使用fetch进行跨域请求的示例:
- 简单fetch请求,和正常使用fetch并无区别
fetch(url) .then(res=>res.json()) .then(json=>console.log(json))
- 表单请求
varfd=newFormData()
fd.append('username','rx')
fd.append('password','rx')
fetch(url,{
method:'POST',
body:fd,
})
.then(res=>res.json())
.then(json=>console.log(json))
- 需要认证的请求
fetch(url,{
/**
*关键就在这里,代表用户是否应该在跨域的情况下发送cookies和HTTPBasicauthentication等验信息以及服务端能否返回Set-Cookie(服务端Session需要使用这个向cookie中设置sessionId)。
*包含三个可选值:omit(从不发送),same-origin(同源才发送),include(总会发送)
*参考链接:
*/
credentials:'include',
})
.then(res=>res.json())
.then(json=>console.log(json))
注:如果想要服务端返回Set-Cookie(SessionId也需要通过这个响应属性去设置)就必须设置这个请求参数!
那么,之后在前端跨域请求的时候就可以愉快地玩耍啦(v^_^)v
以上就是Java跨域问题的处理方式的详细内容,更多关于Java跨域的资料请关注毛票票其它相关文章!