亚洲综合图片区自拍_思思91精品国产综合在线观看_一区二区三区欧美_欧美黑人又粗又大_亚洲人成精品久久久久桥本

天天快看點(diǎn)丨微服務(wù)跨域配置

2022-12-07 10:21:34 來源:51CTO博客

有時(shí)候,我們需要對(duì)所有微服務(wù)跨域請(qǐng)求進(jìn)行處理.


(資料圖)

跨域的說明:

哪些場(chǎng)景是跨域:不同的系統(tǒng)進(jìn)行AJAX的請(qǐng)求的時(shí)候?qū)儆诳缬虻摹?跨域的請(qǐng)求一般是不被允許的。

1.www.jd.com---->www.taobao.com 跨域

2.localhost:8001 —>localhost:8002 跨域

3.www.jd.com:80—>www.jd.com:81 跨域

4.https —>http 跨域。

域名相同,端口相同,協(xié)議相同 就不是跨域。

解決跨域的問題的解決方案:CORS的協(xié)議 (高版本的瀏覽器至少 IE10 google)在服務(wù)端進(jìn)行注解配置(相當(dāng)配置了CORS的配置項(xiàng))springmvc的注解 @CrossOrigin通過在網(wǎng)關(guān)(spring cloud gateway)進(jìn)行統(tǒng)一的配置通過在網(wǎng)關(guān)(nginx里面進(jìn)行配置CORS)JSONP的方式(了解) 利用JS的漏洞的實(shí)現(xiàn)跨域,而且只支持GET請(qǐng)求 不支持其他的請(qǐng)求。

解決方式涉及到圖如下:

通過@CrossOrigin()注解實(shí)現(xiàn)

如果都需要跨域處理,該方式需要在每一個(gè)Controller類上配置。

另外我們一般在SpringCloudGateway網(wǎng)關(guān)配置

spring:  cloud:    gateway:      globalcors:        corsConfigurations:          "[/**]":            allowedOriginPatterns: "*"            allowed-methods: "*"            allowed-headers: "*"            allow-credentials: true            exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"

如果不想配置到y(tǒng)ml也可以代碼寫在網(wǎng)關(guān)模塊中

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpMethod;import org.springframework.http.HttpStatus;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.web.cors.reactive.CorsUtils;import org.springframework.web.server.ServerWebExchange;import org.springframework.web.server.WebFilter;import org.springframework.web.server.WebFilterChain;import reactor.core.publisher.Mono;/** * 跨域配置  */@Configurationpublic class CorsConfig{    /**     * 這里為支持的請(qǐng)求頭,如果有自定義的header字段請(qǐng)自己添加     */    private static final String ALLOWED_HEADERS = "X-Requested-With, Content-Type, Authorization, credential, X-XSRF-TOKEN, token, Admin-Token, App-Token";    private static final String ALLOWED_METHODS = "GET,POST,PUT,DELETE,OPTIONS,HEAD";    private static final String ALLOWED_ORIGIN = "*";    private static final String ALLOWED_EXPOSE = "*";    private static final String MAX_AGE = "18000L";    @Bean    public WebFilter corsFilter()    {        return (ServerWebExchange ctx, WebFilterChain chain) -> {            ServerHttpRequest request = ctx.getRequest();            if (CorsUtils.isCorsRequest(request))            {                ServerHttpResponse response = ctx.getResponse();                HttpHeaders headers = response.getHeaders();                headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);                headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);                headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);                headers.add("Access-Control-Expose-Headers", ALLOWED_EXPOSE);                headers.add("Access-Control-Max-Age", MAX_AGE);                headers.add("Access-Control-Allow-Credentials", "true");                if (request.getMethod() == HttpMethod.OPTIONS)                {                    response.setStatusCode(HttpStatus.OK);                    return Mono.empty();                }            }            return chain.filter(ctx);        };    }}

前端頁(yè)面通過不同域名或IP訪問SpringCloud Gateway,那么,此時(shí)直連微服務(wù)和網(wǎng)關(guān)的跨域問題都解決了,是不是很完美?

No~ 問題來了,前端仍然會(huì)報(bào)錯(cuò):“不允許有多個(gè)’Access-Control-Allow-Origin’ CORS頭”。

問題:Vary 和 Access-Control-Allow-Origin 兩個(gè)頭重復(fù)了兩次,其中瀏覽器對(duì)后者有唯一性限制!

解決方式之一:手動(dòng)寫一個(gè) CorsResponseHeaderFilter 的 GlobalFilter 去修改Response中的頭。

import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpHeaders;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;@Componentpublic class CorsResponseHeaderFilter implements GlobalFilter, Ordered {    private static final String ANY = "*";    @Override    public int getOrder() {        // 指定此過濾器位于NettyWriteResponseFilter之后        // 即待處理完響應(yīng)體后接著處理響應(yīng)頭        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;    }    @Override    @SuppressWarnings("serial")    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        return chain.filter(exchange).then(Mono.fromRunnable(() -> {            exchange.getResponse().getHeaders().entrySet().stream()                    .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))                    .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)                            || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)                            || kv.getKey().equals(HttpHeaders.VARY)))                    .forEach(kv ->                    {                        // Vary只需要去重即可                        if(kv.getKey().equals(HttpHeaders.VARY))                            kv.setValue(kv.getValue().stream().distinct().collect(Collectors.toList()));                        else{                            List value = new ArrayList<>();                            if(kv.getValue().contains(ANY)){  //如果包含*,則取*                                value.add(ANY);                                kv.setValue(value);                            }else{                                value.add(kv.getValue().get(0)); // 否則默認(rèn)取第一個(gè)                                kv.setValue(value);                            }                        }                    });        }));    }}

基于SpringCloudGateway網(wǎng)關(guān)配置完成。

標(biāo)簽: 我們需要 進(jìn)行處理 解決方案

上一篇:天天時(shí)訊:機(jī)器學(xué)習(xí)--Kmeans聚類算法
下一篇:當(dāng)前熱點(diǎn)-#yyds干貨盤點(diǎn)# 歌謠學(xué)前端之React中jsx注意事項(xiàng)