關於跨域問題,主要用的比較多的是cros跨域。angularjs
詳細介紹請看https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORSweb
可是,在springmvc+angularjs下支持跨域請求時,出現複雜跨域場景(post + json)失敗的狀況。spring
開始的跨域配置以下:chrome
public class CrossInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { response.addHeader("Access-Control-Allow-Origin","*"); response.addHeader("Access-Control-Allow-Methods","*"); response.addHeader("Access-Control-Max-Age","100"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Allow-Credentials","false"); return super.preHandle(request, response, handler); } }
spring-dispatcher-servlet.xml中配置以下:json
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**/*"/> <bean class="cn.***.filter.CrossInterceptor" /> </mvc:interceptor> </mvc:interceptors>
針對簡單跨域沒問題。可是針對post+json請求卻失敗,提示跨域失敗。跨域
跟蹤springmvc源碼到FrameworkServlet中的doOption方法,發現,接受了option預檢,可是spring主動返回allow,沒有支持跨域的配置。瀏覽器
所以,加入新的配置以下:mvc
public class CrossFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) { // CORS "pre-flight" request response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"); response.addHeader("Access-Control-Allow-Headers", "Content-Type"); response.addHeader("Access-Control-Max-Age", "1800");//30 min } filterChain.doFilter(request, response); } }
web.xml配置以下:app
<filter> <filter-name>cors</filter-name> <filter-class>cn.***.filter.CrossFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
此時,option請求被CrossFilter過濾器接入並賦予跨域響應頭,同時也進入FrameworkServlet中的doOption方法。查看瀏覽器控制檯,發現option請求返回支持跨域信息,後續的post請求進入controller。cors
升級spring版本的後,上述跨域並不支持全部瀏覽器。經測試,Safari正常,chrome異常。從新翻了一下最新的文檔後,獲得最新的跨域配置以下:
<mvc:cors> <mvc:mapping path="/**" allowed-origins="*" allow-credentials="true" max-age="1800" allowed-methods="GET,POST,OPTIONS"/> </mvc:cors>
相比3.x系列,簡單了不少。