Spring cloud zuul跨域(一)
2024-08-26 13:25:16
项目背景:
我们有web和大屏,以及移动端,需要访问微服务接口。
然而大屏时自己打开的网页,在网页中通过js调用我的webapi。出现了跨域情况。
原因:
出现这个问题,是由于跨域请求有2次请求。
第一次:options(查看请求可用性,确定请求后端是否支持请求类型)
第二次:才是你的真实请求。(get/post...)
解决方案:(有缺点,详见最后)
PreFilter
/**
* zuul转发前过滤器
*/
@Component
public class PreFilter extends ZuulFilter {
public PreFilter() {
super();
} @Override
public String filterType() {
return FilterConstants.PRE_TYPE;
} @Override
public int filterOrder() {
return 0;
} @Override
public boolean shouldFilter() {
// return true; RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
//只过滤OPTIONS 请求
if(request.getMethod().equals(RequestMethod.OPTIONS.name())){ return true;
}
return false;
} @Override
public Object run() { RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
HttpServletResponse response = ctx.getResponse(); response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Allow-Headers","authorization, content-type");
response.setHeader("Access-Control-Allow-Methods","POST,GET"); String requestUrl = request.getRequestURL().toString();
String requestUri = request.getRequestURI();
String zuul = requestUrl.substring(0,requestUrl.indexOf(requestUri)); // zuul根路径
ctx.addZuulRequestHeader("zuul", zuul);
//不再路由
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(200); return null;
} }
PostFilter
@Component
public class PostFilter extends ZuulFilter {
protected static final String SEND_ERROR_FILTER_RAN = "sendErrorFilter.ran"; @Override
public String filterType() {
return FilterConstants.POST_TYPE;
} @Override
public int filterOrder() {
return -1;
} @Override
public boolean shouldFilter() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
//只过滤OPTIONS 请求
if(request.getMethod().equals(RequestMethod.OPTIONS.name())){ return false;
}
return true;
} @Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletResponse response = ctx.getResponse();
HttpServletRequest request = ctx.getRequest();
response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials","true");
response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host");
response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");
//允许继续路由
ctx.setSendZuulResponse(true);
ctx.setResponseStatusCode(200);
return null;
}
}
解决思路:让options 请求进入过滤后,允许跨域。
缺点:网页端出现了问题。比如说退出和登录需要刷新两边。
终其原因是由于,header被设置了两边。因为过滤器无法分辨网页提交的get/post和跨域请求的第二次get/post
最新文章
- 建模分析之机器学习算法(附python&;R代码)
- Oracle介绍(初学者必须知道的)
- 自动编号维护SNRO
- shell脚本变量定义注意别跟系统变量重名了……
- 基于Web的数据推送技术(转)
- oracle .bash_profile
- [Redux] Using mapDispatchToProps() Shorthand Notation
- C# Excel操作类
- Square spiral
- document.createElement在IE和Firefox下的差异
- Spark程序开发-环境搭建-程序编写-Debug调试-项目提交
- Java ee第七周作业
- 计蒜客 31434 - 广场车神 - [DP+前缀和]
- MyBatis中的if写法
- ASP.NET 2.0
- sql server查看表占用索引空间(小技巧)
- xib Nib IB 可视化编程详解
- Lombok的安装及入门
- Python 逐行分割大txt文件
- sqlserver2008 R2中查找未使用过的索引