一文解決瀏覽器跨域問題

追風人聊Java發表於2022-04-23

1. 概述

老話說的好:大處著眼,不貪一時之利。太貪心,只會失去更多,知足才能常樂。

 

言歸正傳,今天我們來聊聊 如何解決瀏覽器跨域的問題。

 

2. 跨域問題

2.1 什麼是跨域

跨域,簡單說就是訪問的頁面域名是 www.a.com,而在此頁面中 Ajax 請求介面,請求的是 www.b.com 的介面,出於安全考慮,瀏覽器預設不允許這樣做,便會報錯,提示跨域。

 

至於為什麼瀏覽器預設不允許跨域,允許跨域有什麼安全隱患,這裡就不討論了,本文只是給大家講講在需要跨域的情況下,如何解決跨域問題。

 

當然,如果訪問的頁面和頁面中請求的介面都在一個域名下,就沒有跨域的煩惱了。

 

解決跨域問題,前端、後端都需要配置,只配置一端是不行的。

 

2.2 使用 java 程式碼解決後端跨域

新增一個跨域配置類 CrossDomainConfig,在其中配置允許跨域訪問的url、請求方式、Header等。程式碼如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@Configuration
public class CrossDomainConfig{

    public CrossDomainConfig() {

    }
  private CorsConfiguration buildConfig() {
    
     // 新增cors配置資訊
      CorsConfiguration corsConfiguration = new CorsConfiguration();
     corsConfiguration.addAllowedOrigin("http://localhost:8080");
      // * 代表所有url
        corsConfiguration.addAllowedOrigin("*");

        // 設定允許請求的方式
        corsConfiguration.addAllowedMethod("*");

        // 設定允許的header
        corsConfiguration.addAllowedHeader("*");
        
        // 設定是否傳送cookie資訊
        corsConfiguration.setAllowCredentials(true);

      return corsConfiguration;
  }

    @Bean
    public CorsFilter corsFilter() {
         
        // 為url新增對映路徑
        UrlBasedCorsConfigurationSource crossDomainSource = new UrlBasedCorsConfigurationSource();
        crossDomainSource.registerCorsConfiguration("/**", buildConfig()); 
        
        // 返回重新定義好的配置
        return new CorsFilter(crossDomainSource); 
    } 
}

 

2.3 Nginx 解決後端跨域

在後端介面所在的 server 配置中增加如下配置即可。

# 允許跨域請求的域名,*代表所有
add_header 'Access-Control-Allow-Origin' *;
# 允許帶上cookie請求
add_header 'Access-Control-Allow-Credentials' 'true';
# 允許請求的方法,例如:GET、POST、PUT、DELETE等,*代表所有
add_header 'Access-Control-Allow-Methods' *;
# 允許請求的頭資訊,例如:DNT,X-Mx-ReqToken,Keep-Alive,User-Agent等,*代表所有
add_header 'Access-Control-Allow-Headers' *;

 

對於後端介面來說,Java程式碼 和 Nginx,使用其中一種方法解決跨域即可。

 

2.3 前端 Ajax 解決跨域

只是後端解決跨域,使用 Ajax 預設配置呼叫介面時,介面可以調通,但 Cookie 無法跨域攜帶,需要在 Ajax 呼叫時增加以下配置:

crossDomain:true, //設定跨域為true
xhrFields: {
 withCredentials: true //預設情況下,標準的跨域請求是不會傳送cookie的
},

 

2.4 SameSite 問題 

為了防止 CSRF 攻擊和使用者追蹤,一些瀏覽器的高版本增加並預設開啟了 SameSite 的機制,嚴格控制跨域攜帶 Cookie。

Microsoft Edge 和 Google Chrome 的高版本就預設開啟了 SameSite 機制。

 

SameSite 簡單說,就是瀏覽器在生成 Cookie 時,增加了 Cookie 的安全級別,跨域攜帶是不允許的。

解決的方法有兩個:

1、登入介面在生成 Cookie 時,修改 Cookie 的 SameSite 配置,例如: httponly; secure;SameSite=None

2、在登入介面反向代理的 Nginx 的 location 配置中增加配置:proxy_cookie_path / "/; httponly; secure;SameSite=None";

 

注意:將 Cookie 的 SameSite 設定為 None 的前提是,介面訪問協議必須是 https 的。

 

3. 綜述

今天聊了一下 如何解決瀏覽器跨域的問題,希望可以對大家的工作有所幫助,下一節我們繼續講 Vue 中的高階語法,敬請期待

歡迎幫忙點贊、評論、轉發、加關注 :)

關注追風人聊Java,這裡乾貨滿滿,都是實戰類技術文章,通俗易懂,輕鬆上手。

 

4. 個人公眾號

追風人聊Java,歡迎大家關注

相關文章