1. 程式人生 > 其它 >跨域問題的後臺解決方案

跨域問題的後臺解決方案

技術標籤:Java基礎

通常我們在跨域是會提示如下錯誤:

Access to XMLHttpRequest at 'http://192.168.09.113:9003/dispatch/export' 
from origin 'http://10.2.8.79' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' 
header is present on the requested resource.

那我我們該如何解決這個問題啦,網上提供後臺常用的三種方法:

首先了解下跨域請求引數設定

Access-Control-Allow-Origin:支援哪些來源的請求跨域。

Access-Control-Allow-Methods:支援哪些方法跨域。

Access-Control-Allow-Credentials:跨域請求預設不包含cookie,設定為true可以包含cookie。

Access-Control-Expose-Headers:跨域請求暴露的欄位。

CORS請求時,XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他欄位,就必須在Access-Control-Expose-Headers裡面指定。

Access-Control-Max-Age:表明該響應的有效時間為多少秒。在有效時間內,瀏覽器無須為同一請求再次發起預檢請求。請注意,瀏覽器自身維護了一個最大有效時間,如果該首部欄位的值超過了最大有效時間,將不會生效。

轉載至:https://blog.csdn.net/zhangleiyes123/article/details/101382749

1、重寫WebMvcConfigurer的addCorsMappings方法,解決跨域問題

/**
 * 解決跨域
 */
@Configuration
public class CorsFilter implements WebMvcConfigurer{
 
	
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders()
                //允許使用的請求方法,以逗號隔開
                .allowedMethods("*")
                //表示接受任意域名請求
                .allowedOrigins("*")
                //表示是否允許傳送Cookie。預設情況下Cookie不包括在CORS請求中。當設為true時表示伺服器明確許可,Cookie可以包含在請求中一起傳送給伺服器。
                .allowCredentials(true)
                //快取此次請求的秒數。在這個時間範圍內,所有同類型的請求都將不再發送預檢請求而是直接使用此次返回的頭作為判斷依據,非常有用,大幅優化請求次數
                .maxAge(3600);
    }
}

2、重寫Filter(過濾器)中doFilter方法


/**
 * 使用Filter解決跨域
 */
@Component
public class CorsFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) {
 
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //該欄位必填。它的值要麼是請求時Origin欄位的具體值,要麼是一個*,表示接受任意域名的請求。
        response.setHeader("Access-Control-Allow-Origin", "*");
        //該欄位必填。它的值是逗號分隔的一個具體的字串或者*,表明伺服器支援的所有跨域請求的方法。注意,返回的是所有支援的方法,而不單是瀏覽器請求的那個方法。這是為了避免多次"預檢"請求。
        response.setHeader("Access-Control-Allow-Methods", "*");
        //該欄位可選,用來指定本次預檢請求的有效期,單位為秒。在有效期間,不用發出另一條預檢請求。
        //response.setHeader("Access-Control-Max-Age", "3600");
        //該欄位可選。它的值是一個布林值,表示是否允許傳送Cookie.預設情況下,不發生Cookie,即:false。對伺服器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type欄位的型別是application/json,這個值只能設為true。如果伺服器不要瀏覽器傳送Cookie,刪除該欄位即可。
        //response.setHeader("Access-Control-Allow-Credentials", "true");
        //該欄位可選。CORS請求時,XMLHttpRequest物件的getResponseHeader()方法只能拿到6個基本欄位:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他欄位,就必須在Access-Control-Expose-Headers裡面指定。
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        filterChain.doFilter(servletRequest, servletResponse);
    }
 
    @Override
    public void destroy() {
 
    }
}

3、在匯出的頭部配置如下設定

        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //設定允許所有來源都可以跨域
        response.setHeader("Access-Control-Allow-Origin", "*");
        //設定允許跨域的請求方式post,get,put,*代表所有請求方式
        response.setHeader("Access-Control-Allow-Methods", "*");
        //該欄位可選,用來指定本次預檢請求的有效期,單位為秒。在有效期間,不用發出另一條預檢請求。
        //response.setHeader("Access-Control-Max-Age", "3600");
       

4、利用nginx解決跨域問題

此時統一通過nginx訪問前後端項,通過/resource標識轉發到後端專案。瀏覽器同源策略記錄的就是http://192.168.137.189:8080/,瀏覽器也只訪問這個nginx的8080地址,跨域問題也就得到了解決

server
{
    listen       8080;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Headers X-Requested-With;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

    location /resource {
        rewrite  ^/resource/?(.*)$ /$1 break;
        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://192.168.137.189:8082/; # 轉發地址
    }
}

5、閘道器配置允許跨域請求


@Configuration
public class GulimallCorsConfiguration {
    /**
     * 功能描述:閘道器統一配置允許跨域
     *
     * @author cakin
     * @date 2020/10/25
     * @return CorsWebFilter 跨域配置過濾器
     */
    @Bean
    public CorsWebFilter corsWebFilter(){
        // 跨域配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 跨域配置
        CorsConfiguration corsConfiguration = new CorsConfiguration();
 
        // 1 配置跨域
        // 允許所有頭進行跨域
        corsConfiguration.addAllowedHeader("*");
        // 允許所有請求方式進行跨域
        corsConfiguration.addAllowedMethod("*");
        // 允許所有請求來源進行跨域
        corsConfiguration.addAllowedOrigin("*");
        // 允許攜帶cookie進行跨域
        corsConfiguration.setAllowCredentials(true);
        // 2 任意路徑都允許第1步配置的跨域
        source.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsWebFilter(source);
    }
}