• Spring cloud zuul跨域(一)


    项目背景:
    我们有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

  • 相关阅读:
    编程实现折半法查找
    浅谈C++多态性
    纯虚函数的使用汇总
    虚函数如何实现多态 ?
    重载(overload),覆盖(override),隐藏(hide)的区别
    Qt入门之常用Qt标准对话框之QMessageBox
    Qt5学习笔记(5)——列表框QListWidget类
    python 文件的方法
    python---while循环
    python ---strip()方法,split()方法,删除字符串开头或结尾,字符串分隔
  • 原文地址:https://www.cnblogs.com/hanjun0612/p/10783070.html
Copyright © 2020-2023  润新知