说明
总结了一下SSM中解决跨域的几种方式。如果项目是用SpringBoot构建的,则有更加优雅的解决方式:https://www.cnblogs.com/phdeblog/p/13260784.html
当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。对应到当前场景就是,项目前后端分离,不管是开发阶段,还是最后部署,前后端代码都不在一个服务器上。
如果前后台是通过session进行身份认证,那么前端每次访问后台的时候,都会携带一个cookie,比如ajax(axios也一样)发起请求时设置
xhrFields:{
withCredentials:true},
这个时候如果后台仅仅设置
response.setHeader("Access-Control-Allow-Origin", "*");
是没有效果的,依然存在跨域问题。如果前端携带cookie,后台必须指定详细的ip,例如把“*”换成“http://localhost:8081”。
知道这一点后,就可以根据不同的业务场景,来编写合适的过滤器了。
版本一:简易版
适用于开发阶段,不需要记录用户状态、前端没有携带cookie时,则可以这么做:
过滤器
public class SimpleCorsFilter implementsFilter {
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers","Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Max-Age", "0");
filterChain.doFilter(servletRequest, servletResponse);
}
}
如果前端携带cookie,可以把 response.setHeader("Access-Control-Allow-Origin", "*");中的*换成具体的ip+端口, 例如:http://127.0.0.1:8080
配置web.xml
SimpleCorsFilter
czams.front.filter.SimpleCorsFilter
SimpleCorsFilter
/*
版本二:选择是否开启跨域
在上面的基础上,经过如下改造后,可在web.xml选择是否开启跨域
过滤器
public class SimpleCorsFilter implementsFilter {private boolean isCross = false;private final ListallowedOrigin = Arrays.asList("http://192.168.1.202:5500","http://127.0.0.1:5500");
@Overridepublic voiddestroy() {
isCross= false;
}
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {if(isCross){
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;
String origin= request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", allowedOrigin.contains(origin) ?origin:"");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers","Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Max-Age", "0");
response.setHeader("Access-Control-Allow-Credentials" , "true");
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
String isCrossStr= filterConfig.getInitParameter("isCross");
isCross= isCrossStr.equals("true");
}}
在Arrays.asList()方法里配置ip。
web.xml
SimpleCorsFilter
czams.front.filter.SimpleCorsFilter
isCross
true
SimpleCorsFilter
/*
通过配置web.xml中的isCross变量选择是否开启跨域。
版本三:在web.xml中配置ip地址
如果觉得在代码里改ip太麻烦了,也可以选择从配置文件中读取
过滤器
public class SimpleCorsFilter implementsFilter {private boolean isCross = false;
private ListallowedOrigin = null;
@Overridepublic voiddestroy() {
isCross= false;
}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;
String origin= request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", allowedOrigin.contains(origin) ?origin:"");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers","Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Max-Age", "0");
response.setHeader("Access-Control-Allow-Credentials" , "true");
filterChain.doFilter(servletRequest, servletResponse);
}
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
String isCrossStr= filterConfig.getInitParameter("isCross");
isCross= isCrossStr.equals("true");
String origin= filterConfig.getInitParameter("origin");
String[] split= origin.split(",");
allowedOrigin=Arrays.asList(split);
}
}
web.xml
注意逗号隔开,不加引号
SimpleCorsFilter
czams.front.filter.SimpleCorsFilter
isCross
true
origin
http://127.0.0.1:5500,http://192.168.1.202:5500,http://localhost:5500
SimpleCorsFilter
/*
其他
如果不想自己写,也可以导一下别人的包,配置一下过滤器即可
添加依赖
com.thetransactioncompany
cors-filter
2.5
com.thetransactioncompany
java-property-utils
1.10
web.xml
CORS
com.thetransactioncompany.cors.CORSFilter
cors.allowOrigin
*
cors.supportedMethods
GET, POST, HEAD, PUT, DELETE
cors.supportedHeaders
Accept, Origin, X-Requested-With, Content-Type, Last-Modified
cors.exposedHeaders
Set-Cookie
cors.supportsCredentials
true
CORS
/*
参数也可以根据个人需要进行适当修改。