Spring Boot:如何解決跨域問題

相關標籤:1.什麼是網域名稱解析及其工作原理
2. Alibaba Cloud DNS

Spring Boot 跨域問題簡介

跨域問題的原因:瀏覽器出於安全考慮,限制對本網站以外資源的訪問。

Spring Boot 跨域問題。跨域問題現象


被 CORS 策略阻止:請求的資源上不存在 Access-Control-Allow-Origin 頭部資訊
以上提示表示您正在訪問的資源地址被 CORS 協議阻止,Header 中未找到 Access-Control-Allow-Origin 參數

跨域問題分析

跨域問題的原因:瀏覽器出於安全考慮,限制對本網站以外資源的訪問。
例如,如果您有一個網站 127.0.0.1:8080/,並在上面掛了一個頁面,那麼在該頁面中,您可以不受限制地訪問本網站的資源,但如果訪問其他網站(如 127.0.0.1:8081)的資源,則會受到限制。
注意:此處將協議、網域名稱和連接埠都相同的視為同一網站。

Spring Boot 跨域問題。但帶有 src 屬性的標籤不受此限制,如 img、script 等。
回顧歷史,以前程式的前後端不分離,頁面和請求介面在同一個網域名稱和連接埠下。瀏覽器認為來自本網站的頁面請求同一網站的介面,長期以來一直允許這樣做。

Spring Boot 跨域問題。例如,127.0.0.1:8080/index.html 請求 127.0.0.1:8080/a/b/c/userList 介面,這是可以的
而現在前後端分離,頁面和介面通常不在同一個程式中,因此不再被允許,會拋出異常。

Spring Boot 跨域問題。什麼是源和跨域





源(origin)由協議、網域名稱和連接埠號碼組成。

一個 URL 由協議、網域名稱、連接埠和路徑組成。如果兩個 URL 的協議、網域名稱和連接埠都相同,則為同源。否則,只要協議、網域名稱、連接埠中有任意一項不同,即為跨域。
以 https://www.baidu.com/index.html 為例的跨域比較:

什麼是同源策略?
同源策略是一種約定。它是瀏覽器最核心、最基本的安全功能。如果缺少同源策略,瀏覽器的正常功能可能會受到影響。可以說 Web 是建立在同源策略基礎之上的,瀏覽器只是同源策略的一種實現。
同源策略又分為以下兩種:
1.DOM 同源策略:禁止操作不同源的 DOM。主要情境是 iframe 跨域的情況,不同網域名稱的 iframe 被限制互相訪問。
2.XMLHttpRequest 同源策略:禁止使用 XHR 對象向不同源的伺服器位址發起 HTTP 要求。
Spring Boot:跨域問題解決

1. Spring Boot 跨域問題。建立過濾器解決跨域

專案的前後端分別部署,因此需要解決跨域問題。我們使用 Cookie 儲存使用者登入資訊,在 Spring 攔截器中控制許可權。當許可權不匹配時,直接返回固定的 JSON 結果給使用者。使用者登入時可以正常使用;當使用者退出登入或令牌到期時,由於攔截器和跨域處理的順序問題,會出現跨域異常。我們知道,一個 HTTP 要求先經過過濾器,然後到達 Servlet 後再由攔截器處理。如果將 CORS 配置放在過濾器中,就可以優先於許可權攔截器執行。
@Configuration

public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);

UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}

2. 基於 WebMvcConfigurerAdapter 配置加入 CORS 解決跨域

前端可以通過 JSONP 解決跨域,但 JSONP 只能發送 GET 請求,無法發送其他類型的請求,在 RESTful 風格的應用中非常局限,因此推薦在後端通過 CORS(Cross-Origin Resource Sharing,跨域資源共用)來解決跨域問題。這個方案並非 Spring Boot 專屬,在傳統的 SSM 架構中也可以使用 CORS 解決跨域問題,只不過以前是在 XML 檔案中配置 CORS,現在可以通過實現 WebMvcConfigurer 介面並重寫 addCorsMappings 方法來解決。
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
.maxAge(3600);
}
}
3. Controller 配置 CORS
在 Controller 方法上配置 CORS,可以在 @RequestMapping 註解的處理方法上添加 @CrossOrigin 註解以啟用 CORS(預設情況下 @CrossOrigin 允許所有來源和 @RequestMapping 註解中指定的 HTTP 方法):
@RestController _
@RequestMapping ( " / account" )
public class AccountController {
@CrossOrigin _
@ GetMapping ( "/ {id}" )
public Account retrieve ( @ PathVariable) Long id )
// ...
A
@ DeleteMapping ( "/ {id}" )
public void remove ( @PathVariable _ Long id ) {
// ...
}
}

其中 @CrossOrigin 的參數說明:
@CrossOrigin 表示允許所有 URL 訪問該資源 @CrossOrigin ( origins = " http://127.0.0.1:8080")//表示僅允許該 URL 跨域訪問此 Controller 代碼說明:@CrossOrigin 這個註解使用起來很方便,可以用在方法上,也可以用在類上。如果不設定其 value 屬性或 origins 屬性,預設允許所有 URL/網域名稱訪問。
1.value 屬性可以設定多個 URL。
2.origins 屬性也可以設定多個 URL。
3.maxAge 屬性指定預檢請求的緩衝有效期間持續時間上限。
4.allowCredentials 屬性工作表示是否可以發送和處理 Cookie。預設為 false
5.allowedHeaders 屬性工作表示允許哪些要求標頭。
6.methods 屬性工作表示允許的要求方法,預設為 GET、POST、HEAD。
@CrossOrigin 不生效的原因
1. Spring MVC 版本必須是 4.2 及以上才支援 @CrossOrigin

2. 並非 @CrossOrigin 沒有解決跨域請求問題,而是不正確的請求導致無法獲得預期響應,從而使瀏覽器提示跨域問題。
@CrossOrigin 註解在 Controller 註解上方,跨域問題仍然存在。其中一個解決方案是:
在 @RequestMapping 註解中未指定 GET 和 POST 方法。指定後問題得到解決。
類似代碼如下:
@CrossOrigin _
@RestController _
public class person {

@RequestMapping ( method _ = RequestMethod.GET ) _ _
public String add ( ) {
// some code
}
}

相關文章

探索更多特惠

  1. 簡訊服務與Direct Mail

    5萬封郵件包低至1.99 USD起,120條簡訊僅需1.00 USD起

phone 聯絡我們
Hi, I'm Alibaba Cloud AI Assistant!
I can help with questions and solutions.