首頁  >  文章  >  Java  >  Springboot如何解決ajax自訂headers的跨域請求問題

Springboot如何解決ajax自訂headers的跨域請求問題

王林
王林轉載
2023-05-16 12:43:061083瀏覽

1、什麼是跨域

由於瀏覽器同源策略(同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支援JavaScript 的瀏覽器都會使用這個策略。所謂同源是指,域名,協議,端口相同。),凡是發送請求url的協議、域名、端口三者之間任一與當前頁面地址不同即為跨域。

具體可以查看下表:

Springboot如何解決ajax自訂headers的跨域請求問題

2、springboot如何解決跨域問題

1.普通跨域請求解決方案:

①請求介面新增註解@CrossOrigin(origins = "http://127.0.0.1:8020", maxAge = 3600)

#說明:origins = "http://127.0.0.1:8020" origins值為目前請求該介面的網域

②通用設定(所有介面都允許跨網域請求)

新增一個configration類別或在Application中加入CorsFilter和CorsConfiguration方法

@Configuration 
public class CorsConfig { 
  private CorsConfiguration buildConfig() { 
    CorsConfiguration corsConfiguration = new CorsConfiguration(); 
    corsConfiguration.addAllowedOrigin("*"); // 1允许任何域名使用
    corsConfiguration.addAllowedHeader("*"); // 2允许任何头
    corsConfiguration.addAllowedMethod("*"); // 3允许任何方法(post、get等) 
    return corsConfiguration; 
  } 

  @Bean 
  public CorsFilter corsFilter() { 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 
    source.registerCorsConfiguration("/**", buildConfig()); // 4 
    return new CorsFilter(source); 
  } 
}

2.ajax自訂headers的跨網域請求

$.ajax({
    type:"GET",
    url:"http://localhost:8766/main/currency/sginInState",
    dataType:"JSON",
    data:{
      uid:userId
    },
    beforeSend: function (XMLHttpRequest) {
      XMLHttpRequest.setRequestHeader("Authorization", access_token);
    },
    success:function(res){
      console.log(res.code)
    }
  })

此時請求http: //localhost:8766/main/currency/sginInState介面發現OPTIONS http://localhost:8766/main/currency/sginInState 500錯誤,普通跨網域的解決方案已經無法解決這個問題,為什麼會出現OPTIONS請求呢?

Springboot如何解決ajax自訂headers的跨域請求問題

原因

瀏覽器會在傳送真正請求之前,先傳送一個方法為OPTIONS的預檢請求Preflighted requests 這個請求是用來驗證本次請求是否安全的,但是並不是所有請求都會發送,需要符合以下條件:

#•請求方法不是GET/HEAD/POST
•POST請求的Content-Type並非application/x-www-form-urlencoded, multipart/form-data, 或text/plain

•請求設置了自定義的header字段

對於管理端的接口,我有對介面進行權限校驗,每次要求都需要在header中攜帶自訂的欄位(token),所以瀏覽器會多發送一個OPTIONS請求去驗證此次請求的安全性。

為何OPTIONS請求是500呢?

OPTIONS請求只會攜帶自訂的字段,並不會將相應的值帶入進去,而後台校驗token字段時token為NULL,所以驗證不通過,拋出了一個異常。

那麼我們現在來解決這個問題:

① spring boot專案application.yml中新增

spring:
mvc:
dispatch-options-request: true

注意:這種解決方案可能在某些情況下並不能解決OPTIONS問題,原因可能是環境問題,也可能是複雜的自訂filter過濾器配置問題等。

②新增過濾器配置

第一步:手寫RequestFilter請求過濾器配置類別此類需要實作HandlerInterceptor類,HandlerInterceptor類別是org.springframework.web.servlet.HandlerInterceptor下的。

具體程式碼實作:

@Component
public class RequestFilter implements HandlerInterceptor {
  public boolean preHandler(HttpServletRequest request,HttpServletResponse response,Object handler){
    response.setHeader("Access-Control-Allow-Origin", "*");
    response.setHeader("Access-Control-Allow-Credentials", "true");
    response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
    response.setHeader("Access-Control-Max-Age", "86400");
    response.setHeader("Access-Control-Allow-Headers", "Authorization");
    // 如果是OPTIONS请求则结束
    if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
      response.setStatus(HttpStatus.NO_CONTENT.value());
      return false;
    }
    return true;
  }
}

第二步:手寫MyWebConfiguration此類需要繼承WebMvcConfigurationSupport。

注意:WebMvcConfigurationSupport是2.x版本以上的,1.x版本為WebMvcConfigurerAdapter 。

具體程式碼實作:

@Component
public class MyWebConfiguration extends WebMvcConfigurationSupport{
  @Resource
  private RequestFilter requestFilter;
  @Override
  public void addInterceptors(InterceptorRegistry registry) {
    // 跨域拦截器
    registry.addInterceptor(requestFilter).addPathPatterns("/**");
  }
}

以上是Springboot如何解決ajax自訂headers的跨域請求問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除