SpringBoot_Ajax_處理options請求

function https(url,type,data,header,callback) {
    $.ajax({
        url:url,
        type:type,
        data:data,
        contentType:'application/json',
        headers:header,
        crossDomain:true,
        success:function (data,status) {
            console.log(data);
            if(data.errorNo == "20001" || data.errorNo == "20002"){
            //令牌失效
                window.location.href = "./lyear_pages_login.html";
            }else if(data.errorNo == "0"){
                callback(data,status);
            }else{
                alert(data.errorInfo);
            }
        },
        error:function (XMLHttpRequest,textStatus,errorThrown) {
            if(textStatus==='timeout'){
                alert('請求超時');
                setTimeout(function(){
                    alert('重新請求');
                },2000);
            }
            window.location.href = "./lyear_pages_login.html";
        }
    })
}

使用改模板發送一個請求到本地服務器的時候,會出現以下的錯誤:403

General:
Request URL: http://localhost:9090/....
Request Method: OPTIONS
Status Code: 403 
Remote Address: [::1]:9090
Referrer Policy: no-referrer-when-downgrade

Response Headers:
Connection: keep-alive
Date: Sat, 28 Mar 2020 07:12:49 GMT
Keep-Alive: timeout=60
Transfer-Encoding: chunked
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers

Request Headers:
Provisional headers are shown
Access-Control-Request-Headers: authentication,content-type
Access-Control-Request-Method: GET
Origin: http://localhost:63342
Referer: http://localhost:63342/lyear_2_LightYear-admin/index.html
Sec-Fetch-Mode: cors
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36

可以看到這個請求是OPTIONS的,而不是我們預期的GET或是POST。

原因在於:https://www.cnblogs.com/wanghuijie/p/preflighted_request.html

也就是這是一個Preflighted Request,所以發送真正的請求之前會發送一個OPTIONS請求用於試探服務器是否能接受真正的請求。如果options獲得的迴應是拒絕性質的,比如404\403\500等http狀態,就會停止post、get等請求的發出。

關於Preflighted Request(帶預檢的跨域請求)發生在:

(文檔地址:https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#The_HTTP_request_headers)

  1. 請求方法不是GET/HEAD/POST
  2. POST請求的Content-Type並非application/x-www-form-urlencodedmultipart/form-data, 或text/plain
  3. 請求設置了自定義的header字段

以上封裝的請求符合了2和3。而且在使用token驗證和大量json數據的請求中是不可避免的。

解決方法:給OPTIONS請求一個正確的響應。

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**");
    }

    /**
    *@Author: Czc on 2020/3/28 14:18
    *@param:
    *@return:
    *@Description: 跨域請求配置
    **/
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
}

addCorsMappings方法對OPTIONS方法返回了允許的響應。

options請求

然後再發出真正的請求。

real request 當然,就像登陸校驗攔截器一樣,也可以通過攔截器對請求進行處理,再響應的報文頭部中加上跨域請求相關的字段。然後對於OPTIONS請求直接截斷返回。其他的請求繼續進行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章