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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM