成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

zuul實現(xiàn)Cors跨域的兩種方式(https)

wuaiqiu / 1925人閱讀

摘要:大家都知道可以通過實現(xiàn)跨域。第一種方式在服務(wù)下添加一個實現(xiàn)跨域,實現(xiàn)起來方便。前端服務(wù)和后端服務(wù)在同一臺服務(wù)器上,服務(wù)調(diào)用服務(wù)時,服務(wù)通過負載均衡進入服務(wù)時時,服務(wù)的請求跨域成功,時,服務(wù)的請求跨域失敗。

大家都知道spring boot 可以通過@CrossOrigin實現(xiàn)跨域。但是在spring cloud 里,如果要粒度那么細的去控制跨域,這個就太繁瑣了,所以一般來說,會在路由zuul里實現(xiàn)。

第一種方式:corsFilter

在zuul服務(wù)下添加一個corsFilter實現(xiàn)跨域,實現(xiàn)起來方便。代碼如下

@Configuration
public class GateWayCorsConfig {
   @Bean
    public FilterRegistrationBean corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        //這個請求頭在https中會出現(xiàn),但是有點問題,下面我會說
        //config.addExposedHeader("X-forwared-port, X-forwarded-host"); 
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

經(jīng)過測試,這樣的配置在http的情況下跨域是OK的,但是當我的環(huán)境切換的https的情況下就發(fā)生了奇怪的問題。說明一下我遇到的問題。
前端 服務(wù)A后端服務(wù)B 在同一臺服務(wù)器上,服務(wù)A 調(diào)用 服務(wù)B 時,服務(wù)A通過負載均衡進入服務(wù)B時:
http時,服務(wù)A的請求跨域成功,https時,服務(wù)A的請求跨域失敗。
也就是端口為443的時候,會被認為跨域失?。。?/strong>
我一開始對比了請求頭,以為是少了ExposedHeader的"X-forwared-port, X-forwarded-host",但是添加后,還是失敗。因為急著上線,所以我沒有去深入測試到底什么原因引起的https請求跨域失敗。(所以如果大家發(fā)現(xiàn)我哪里寫的不對,請務(wù)必通知我,讓我也明白為什么失??!謝謝?。?/p> 第二種方式:繼承ZuulFilter

因為第一種方式在https下失敗后,我嘗試了用zuulfilter實現(xiàn)cors的方式
一共需要兩個filiter:一個pre, 一個post

Pre-Filter:

@Component
public class FirstFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(FirstFilter.class);

    @Override
    public String filterType() {
        /*
        pre:可以在請求被路由之前調(diào)用
        route:在路由請求時候被調(diào)用
        post:在route和error過濾器之后被調(diào)用
        error:處理請求時發(fā)生錯誤時被調(diào)用
        * */
        // 前置過濾器
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        //// 優(yōu)先級為0,數(shù)字越大,優(yōu)先級越低
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //只過濾OPTIONS 請求
        if(request.getMethod().equals(RequestMethod.OPTIONS.name())){
            return true;
        }

        return false;
    }

    @Override
    public Object run() {
        logger.debug("*****************FirstFilter run start*****************");
        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-Allow-Headers","authorization, content-type");
        response.setHeader("Access-Control-Allow-Methods","POST,GET");
        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(false);
        ctx.setResponseStatusCode(200);
        logger.debug("*****************FirstFilter run end*****************");
        return null;
    }
}

Pre-Filter 用來處理預(yù)處理OPTIONS請求,當發(fā)現(xiàn)是OPTIONS請求的時候,給出跨域響應(yīng)頭,并且不對其進行zuul路由,直接返回成功(200), 給前端服務(wù)允許跨域

post-Filter :

@Component
public class PostFilter extends ZuulFilter {

    private Logger logger = LoggerFactory.getLogger(PostFilter.class);

    @Override
    public String filterType() {
        /*
        pre:可以在請求被路由之前調(diào)用
        route:在路由請求時候被調(diào)用
        post:在route和error過濾器之后被調(diào)用
        error:處理請求時發(fā)生錯誤時被調(diào)用
        * */
        // 前置過濾器
        return FilterConstants.POST_TYPE;
    }

    @Override
    public int filterOrder() {
        //// 優(yōu)先級為0,數(shù)字越大,優(yōu)先級越低
        return 2;
    }
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        //過濾各種POST請求
        if(request.getMethod().equals(RequestMethod.OPTIONS.name())){
            return false;
        }
        return true;
    }

    @Override
    public Object run() {
        logger.debug("*****************PostFilter run start*****************");
        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");
        //允許繼續(xù)路由
        ctx.setSendZuulResponse(true);
        ctx.setResponseStatusCode(200);
        logger.debug("*****************PostFilter run end*****************");
        return null;
    }
}

Post-Filter 用來處理 預(yù)處理OPTIONS以外的請求,對于正常的請求,不但要給出跨域請求頭,還需要允許請求進行路由(否則你的請求到這兒就結(jié)束啦),然后返回狀態(tài)碼200。(emmmm……這里要不要返回200,我覺得可能還要想一想……)

按照以上方式配置的話,方法一出現(xiàn)的問題,就得到了解決。服務(wù)A能夠正常請求服務(wù)B了

雖然是正常實現(xiàn)了需求,但是感覺還是存在很多疑惑,希望大家看到的話,能給我指出不足。一起討論!

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76601.html

相關(guān)文章

  • js跨域問題及常用兩種解決方案

    摘要:類似這樣而在客戶端我們只需要定義一個預(yù)定好的回調(diào)函數(shù)即可。處理跨域請求得到的數(shù)據(jù)其中的是我們在客戶端定義好的在數(shù)據(jù)請求成功后要執(zhí)行的回調(diào)函數(shù)。 跨域產(chǎn)生的原因 跨域是由瀏覽器的同源策略引起的,即不同源(協(xié)議,域名,端口中其中有一個不同)的js是不能讀取對方的資源的。當要網(wǎng)站中的js要請求其他網(wǎng)站的數(shù)據(jù)時就會產(chǎn)生跨域問題,就像下面這樣,瀏覽器會報錯。 showImg(https://se...

    gyl_coder 評論0 收藏0
  • 解決跨域兩種方案JSONP和CORS

    摘要:由于第二種方法如今已經(jīng)采用的非常少,所以我們在這兒不做講解一帶填充的是一種可以在中繞過同源策略,并發(fā)起跨域請求的使用模式,可以啟動的跨域請求同源策略有一個顯著的例外,腳本元素是可以規(guī)避檢查的。 講跨域之前,我們先來講同源策略(SOP),同源策略是網(wǎng)景公司提出的一個著名安全策略。所謂同源就是域名、協(xié)議、端口相同。例如http://www.12306.cn中,http就是超文本傳輸協(xié)議,1...

    曹金海 評論0 收藏0
  • Web開發(fā)之跨域跨域資源共享

    摘要:例外當涉及到同源策略時,有兩個主要的例外授信范圍兩個相互之間高度互信的域名,如公司域名,不遵守同源策略的限制。端口未將端口號加入到同源策略的組成部分之中,因此和屬于同源并且不受任何限制。 原文鏈接:http://www.devsai.com/2016/11/24/talk-CORS/ 同源策略(same origin policy) 1995年,同源政策由 Netscape 公司引入瀏...

    Eastboat 評論0 收藏0
  • 前端基本功-常見概念(一)

    摘要:前端基本功常見概念一點這里前端基本功常見概念二點這里前端基本功常見概念三點這里什么是原型鏈當一個引用類型繼承另一個引用類型的屬性和方法時候就會產(chǎn)生一個原型鏈。函數(shù)式編程是聲明式而不是命令式,并且應(yīng)用程序狀態(tài)通過純函數(shù)流轉(zhuǎn)。 前端基本功-常見概念(一) 點這里前端基本功-常見概念(二) 點這里前端基本功-常見概念(三) 點這里 1.什么是原型鏈 當一個引用類型繼承另一個引用類型的屬性和方...

    bladefury 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<