您好,登錄后才能下訂單哦!
本篇內容介紹了“如何使用SpringCloudApiGateway支持Cors跨域請求”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
公司的項目需要前后端分離,vue+java,這時候就需要支持Cors跨域請求了。最近對zuul進行升級,假如說zuul是1.0的話,api gateway就是2.0的網關,支持ws等,基于NIO,各方面還是強大的。
import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator; import org.springframework.cloud.gateway.route.RouteDefinitionLocator; 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; /** * SpringApiGateway Cors */ @Configuration public class RouteConfiguration { //這里為支持的請求頭,如果有自定義的header字段請自己添加(不知道為什么不能使用*) private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client"; private static final String ALLOWED_METHODS = "*"; private static final String ALLOWED_ORIGIN = "*"; private static final String ALLOWED_Expose = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client"; 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-Origin", ALLOWED_ORIGIN); headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS); headers.add("Access-Control-Max-Age", MAX_AGE); headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS); headers.add("Access-Control-Expose-Headers", ALLOWED_Expose); headers.add("Access-Control-Allow-Credentials", "true"); if (request.getMethod() == HttpMethod.OPTIONS) { response.setStatusCode(HttpStatus.OK); return Mono.empty(); } } return chain.filter(ctx); }; } /** * *如果使用了注冊中心(如:Eureka),進行控制則需要增加如下配置 */ @Bean public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient) { return new DiscoveryClientRouteDefinitionLocator(discoveryClient); } }
官方文檔提及到還有另外一種方式,就是通過yml來配置。
spring: cloud: gateway: globalcors: corsConfigurations: '[/**]': allowedOrigins: "https://blog.csdn.net/moshowgame" allowedMethods: - GET
跨域問題是出于瀏覽器的【同源策略】限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。
可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。
所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)
由于我們現在是采用的前后端分離的微服務架構,前端和后端必定存在跨域問題。解決跨域問題可以采用CORS。
CORS 是一個 W3C 標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。
CORS需要瀏覽器和服務器同時支持。但是目前基本上瀏覽器都支持,所以我們只要保證服務器端服務器實現了 CORS 接口,就可以跨源通信。
瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。
解決跨域問題,就是在服務器端給響應添加頭信息
Name | Required | Comments |
---|---|---|
Access-Control-Allow-Origin | 必填 | 允許請求的域 |
Access-Control-Allow-Methods | 必填 | 允許請求的方法 |
Access-Control-Allow-Headers | 可選 | 預檢請求后,告知發送請求需要有的頭部 |
Access-Control-Allow-Credentials | 可選 | 表示是否允許發送cookie,默認false; |
Access-Control-Max-Age | 可選 | 本次預檢的有效期,單位:秒; |
在spring boot中給我們提供了 @CrossOrigin 注解用于解決跨域問題。
使用場景要求:jdk1.8+、Spring4.2+
只需要在我們需要的controller上加@CrossOrigin
@RestController //實現跨域注解 //origin="*"代表所有域名都可訪問 //maxAge飛行前響應的緩存持續時間的最大年齡,簡單來說就是Cookie的有效期 單位為秒若maxAge是負數,則代表為臨時Cookie,不會被持久化,Cookie信息保存在瀏覽器內存中,瀏覽器關閉Cookie就消失 @CrossOrigin(origins = "*",maxAge = 3600) @RequestMapping("/album") public class AlbumController {}
只需要在spring Cloud Gateway 服務中添加配置就行
spring: application: name: system-gateway cloud: gateway: globalcors: cors-configurations: '[/**]': # 匹配所有請求 allowedOrigins: "*" #跨域處理 允許所有的域 allowedMethods: # 支持的方法 - GET - POST - PUT - DELETE
當然也可以自己利用Gateway的攔截器來手動添加相應的頭信息
default-filters: - AddResponseHeader=Access-Control-Allow-Credentials,true - AddResponseHeader=Access-Control-Allow-Headers,access-control-allow-origin - AddResponseHeader=Access-Control-Allow-Methods,GET - AddResponseHeader=Access-Control-Allow-Origin,* - AddResponseHeader=Access-Control-Allow-Age,3600
location /example { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin *; add_header Access-Control-Max-Age 1728000; add_header Access-Control-Allow-Methods GET,POST,OPTIONS; add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header Content-Type' 'text/plain; charset=utf-8'; add_header Content-Length 0 ; return 204; } + if ($http_origin ~* (https?://(.+\.)?(example\.com$))) { + add_header Access-Control-Allow-Origin $http_origin; + add_header Access-Control-Allow-Credentials true; + add_header Access-Control-Allow-Methods GET,POST,OPTIONS; + add_header Access-Control-Expose-Headers Content-Length,Content-Range; + } proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080/; }
解釋:
if ($request_method = 'OPTIONS') {...} 當請求方法為 OPTIONS 時:
添加允許源 Access-Control-Allow-Origin 為 * (可根據業務需要更改)
添加緩存時長 Access-Control-Max-Age,當下次請求時,無需再發送 OPTIONS 請求
添加允許的方法,允許的首部
添加一個內容長度為0,類型為 text/plain; charset=utf-8 , 返回狀態碼為 204 的首部
if ($http_origin ~* (https?://(.+\.)?(example\.com$))) {...}, 當 origin 為合法域名(可根據業務調整或去除合法域名驗證)時:
添加允許源Access-Control-Allow-Origin為 $http_origin (可根據業務需要更改)
添加允許認證Access-Control-Allow-Credentials為 true ,允許接收客戶端 Cookie(可根據業務需要更改。 但要注意,當設置為true時,Access-Control-Allow-Origin 不允許設置為 *)
添加允許的方法,暴露的首部
至此,完成跨域請求正確響應。
“如何使用SpringCloudApiGateway支持Cors跨域請求”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。