springmvc中跨域問題
阿新 • • 發佈:2018-04-03
work lock cor sock 攔截 bean 對象 thead resources
對於web框架中的跨域問題是一個非常普遍的問題,常見的解決方案也有很多,如:jsonp、cros、websocket等。下面是最近處理springmvc中使用cors解決跨域問題的一些總結。
Filter
具體實現不在詳細描述,基本原理利用filter攔截到所有請求,然後進行跨域設置。
攔截器
-
實現代碼
public class WeCrosInterceptor implements HandlerInterceptor { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getHeader(HttpHeaders.ORIGIN) != null) { response.addHeader("Access-Control-Allow-Origin", "*"); 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; } public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
-
配置
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**/*"/> <bean class="com.***.interceptor.WeCrosInterceptor" /> </mvc:interceptor> </mvc:interceptors>
註意:如果系統中有其他攔截器,要將該攔截器放在第一個。
springmvc4.2之後版本
@CrossOrigin註解
可註解在方法上,也可註解在類上
-
示例
@CrossOrigin(origins = "http://www.zhihu.com") @RequestMapping(value = "/allProductions", method = RequestMethod.GET) public Result getAllOldProductions() { }
xml全局配置
-
所有跨域請求都可以訪問
<mvc:cors> <mvc:mapping path="/**" /> </mvc:cors>
-
細粒度的配置
<mvc:cors> <mvc:mapping path="/api/**" allowed-origins="http://domain1.com, http://domain2.com" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" /> <mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" /> </mvc:cors>
以上兩種方式在正常使用<mvc:annotation-driven 加載情況下完全可以滿足需求。
特殊情況下跨域問題
如果重寫了RequestMappingHandlerMapping,就需要單獨配置,此時會發現全局的xml配置沒有作用了,具體原因是沒有使用springmvc框架解析的跨域配置最終是註入給RequestMappingHandlerMapping這個類的對象的,重寫後的mapping對象不會被註入,怎麽解決這個問題呢?filter
、攔截器都可以解決,但是都用了4.2的版本還要額外配置是不是太low了,經過查看源碼,發現AbstractHandlerMapping有個setCorsConfigurations方法是用來設置跨域配置的,下面最終配置:
<bean name=‘handlerMapping‘ class="com.we.core.web.view.WeRequestMappingHandlerMapping">
<property name="corsConfigurations">
<map>
<entry key="/**">
<bean class="org.springframework.web.cors.CorsConfiguration">
<property name="allowedMethods" value="GET,POST,OPTIONS"/>
<property name="allowedOrigins" value="*"/>
<property name="allowedHeaders" value="*"/>
<property name="allowCredentials" value="true"/>
<property name="maxAge" value="1800"/>
</bean>
</entry>
</map>
</property>
</bean>
無需增加多余配置類,完美解決問題。
springmvc中跨域問題