日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

filter导致跨域失效_【SpringMVC】与权限拦截器冲突导致的Cors跨域设置失效问题...

發(fā)布時間:2024/7/19 javascript 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 filter导致跨域失效_【SpringMVC】与权限拦截器冲突导致的Cors跨域设置失效问题... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

問題描述

前端域名FE.com向后端域名BE.com分別請求訪問優(yōu)惠券的列表和提交新增的優(yōu)惠券,API設(shè)計所用的Method分別為Get和Post,結(jié)果為前一次訪問成功而后一次訪問失敗。這兩次請求都是跨域請求,其中請求1包含一個Get請求,請求2本應(yīng)該包含一個Options請求和一個Post請求,但是只發(fā)生了Options請求。

后端Cors配置

CORS使用SpringMVC自帶的標(biāo)簽全局配置,權(quán)限檢測則實現(xiàn)自定義的攔截器校驗Cookie中的Token信息。

allowed-methods="POST, GET, OPTIONS, DELETE, PUT, HEAD"

allowed-origins="http://test.i.meituan.com"

max-age="3600" path="/**"/>

在復(fù)雜請求的情況下(即請求2),由于預(yù)檢請求不會包含Cookie信息(瀏覽器本身的實現(xiàn)決定其是否發(fā)送Cookie,前端無法控制,并且Chrome是不發(fā)送的),因此被權(quán)限攔截器提前結(jié)束,沒有輸出包含指定頭部信息的響應(yīng)。而一個被瀏覽器認(rèn)為合格的預(yù)檢請求響應(yīng)必須包含如下的Http頭部。

Access-Control-Allow-Origin: http://test.i.meituan.com

Access-Control-Allow-Methods: POST, GET, OPTIONS

Access-Control-Allow-Headers: Content-Type

Access-Control-Max-Age: 86400

為什么會發(fā)生提前結(jié)束這種情況?可以對dispatch()方法進(jìn)行分析。

Handler和攔截器的執(zhí)行順序

DispatchServlet.doDispatch()方法是SpringMVC的核心入口方法,分析發(fā)現(xiàn)所有的攔截器的preHandle()方法的執(zhí)行都在實際Handler的方法(比如某個API對應(yīng)的業(yè)務(wù)方法)之前,其中任意攔截器返回false都會跳過后續(xù)所有處理過程。而SpringMVC對預(yù)檢請求的處理則在PreFlightHandler.handleRequest()中處理,在整個處理鏈條中出于后置位。由于預(yù)檢請求中不帶Cookie,因此先被權(quán)限攔截器攔截。

// Determine handler for the current request.

mappedHandler = getHandler(processedRequest);

//省略代碼

if (!mappedHandler.applyPreHandle(processedRequest, response)) {

return;

}

// Actually invoke the handler.

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

@CrossCors時序分析

除了在XML中設(shè)置全局的CORS配置,Spring提供了@CrossCors,可以注解在類和方法上,是一種更細(xì)粒度的配置方法。SpringMVC把其處理細(xì)節(jié)包裝在getHandler(processedRequest);中,具體邏輯可以簡述為如果請求是預(yù)檢請求,則返回PreFlightHander;否則在攔截器末尾添加一個CorsInterceptor。因此可以看出,@CrossCors相關(guān)的執(zhí)行和全局的類似,也是滯后于權(quán)限攔截器的。

解決方案

方案1:使用Spring-Web自帶的CorsFilter

由于CorsFilter是定義在Web容器中的過濾器(實現(xiàn)了javax.servlet.Filter),因此其執(zhí)行順序先于Servlet,而SpringMVC的入口是DispatchServlet,因此該Filter會先于SpringMVC的所有攔截器執(zhí)行。分析代碼可知,CorsFilter會獲取單個請求對應(yīng)的Cors配置做相應(yīng)的處理。因此可以和很好的結(jié)合,不需要增加額外的代碼。(勘誤:CorsFilter的構(gòu)造需要CorsConfigurationSource實例,并且發(fā)生在SpringMVC配置文件解析之前,因此只能放在Spring的配置文件中,否則會發(fā)生找不到bean的異常;又由于的解析和Spring核心的解析不共享相同的ParserContext上下文,因此SpringMVC的跨域設(shè)置不能植入到CorsFilter中)

if (CorsUtils.isCorsRequest(request)) {

CorsConfiguration corsConfiguration = this.configSource.getCorsConfiguration(request);

if (corsConfiguration != null) {

boolean isValid = this.processor.processRequest(corsConfiguration, request, response);

if (!isValid || CorsUtils.isPreFlightRequest(request)) {

return;

}

}

}

filterChain.doFilter(request, response);

方案2:自己實現(xiàn)Interceptor

與方案1類似,把插入Http頭的功能實現(xiàn)為SpringMVC的攔截器,然后在中聲明為第一順位。

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

if (request.getHeader(HttpHeaders.ORIGIN) != null) {

response.addHeader("Access-Control-Allow-Origin", "http://test.i.meituan.com");

response.addHeader("Access-Control-Allow-Credentials", "true");

response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT, HEAD");

response.addHeader("Access-Control-Allow-Headers", "Content-Type");

response.addHeader("Access-Control-Max-Age", "3600");

}

return true;

}

方案3:增強(qiáng)自定義Interceptor

利用AOP環(huán)繞增強(qiáng)所有自定義攔截器的preHandle()方法,令其跳過預(yù)檢請求的攔截。

@Around(value = "cut()")

public Object processTx(ProceedingJoinPoint jp) throws Throwable {

HttpServletRequest request = (HttpServletRequest) jp.getArgs()[0];

if (request != null && CorsUtils.isPreFlightRequest(request)) {

return true;

} else {

return jp.proceed();

}

}

Reference

總結(jié)

以上是生活随笔為你收集整理的filter导致跨域失效_【SpringMVC】与权限拦截器冲突导致的Cors跨域设置失效问题...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。