關(guān)于跨域資源訪問(wèn)請(qǐng)參考 http://en./wiki/Cross-origin_resource_sharing ,基本原理是在Spring Controller的每一個(gè)請(qǐng)求返回的時(shí)候都加上Access-Control-...header,需要注意的是并不是所有的瀏覽器都支持這些header,使用之前要先了解清楚。
實(shí)現(xiàn)起來(lái)也很簡(jiǎn)單那就是Interceptor,代碼如下:
- public class AccessKeyInterceptor extends HandlerInterceptorAdapter {
-
- private static Log log=LogFactory.getLog(AccessKeyInterceptor.class);
-
- @Autowired
- private IAccessService accessService;
-
- private String accessKeyParameterName="accessKey";
- private List<String> defaultAccessAllowedFrom;
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- String accessKey=request.getParameter(accessKeyParameterName);
- String referer = request.getHeader("Referer");
- URL u = new URL(referer);
- String host = u.getHost().toLowerCase();
- if(accessKey==null){
- log.error("====================================ILLEGAL ACCESS: ACCESS_KEY_MISSING!=======================");
- }else{
- log.debug("====================================ACCESS WITH Access KEY:"+accessKey+"====================");
- IAccess access = accessService.getAccess(UserSessionUtils.getUserSession(request), accessKey);
- if(access!=null){
- defaultAccessAllowedFrom=access.getAccessAllowedFrom();
- }else{
- log.warn("======================================ACCESS KEY:"+accessKey+" DOES NOT EXIST!=================");
- }
- }
- for(String s : defaultAccessAllowedFrom) {
- if(host.matches(s)){
- response.setHeader("Access-Control-Allow-Origin", referer);
- break;
- }
- }
- response.setHeader("Access-Control-Allow-Headers", "Content-Type");
- response.setHeader("Access-Control-Allow-Methods", "GET");
- response.setHeader("Allow", "GET");
- return true;
- }
-
- public List<String> getDefaultAccessAllowedFrom() {
- return defaultAccessAllowedFrom;
- }
-
- public void setDefaultAccessAllowedFrom(List<String> defaultAccessAllowedFrom) {
- this.defaultAccessAllowedFrom = defaultAccessAllowedFrom;
- }
-
- public String getAccessKeyParameterName() {
- return AccessKeyParameterName;
- }
-
- public void setAccessKeyParameterName(String accessKeyParameterName) {
- this.AccessKeyParameterName = AccessKeyParameterName;
- }
- }
其中defaultAccessAllowedFrom是在Spring的配置文件中,主要的配置默認(rèn)授權(quán)訪問(wèn)的url,如下:
- <property name="defaultAccessAllowedFrom">
- <list>
- <value>(.+\.)?(domain\.com)$</value>
- <value>(.+\.)?(192\.168\.0\.10)$</value>
- </list>
- </property>
但是由于Spring默認(rèn)Controller是不處理OPTIONS的請(qǐng)求的,所以必須在web.xml中打開(kāi),如下:
- <servlet>
- <servlet-name>application</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <init-param>
- <param-name>dispatchOptionsRequest</param-name>
- <param-value>true</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>application</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
這樣當(dāng)請(qǐng)求時(shí)POST的時(shí)候前段就會(huì)自動(dòng)先請(qǐng)求OPTIONS,得到許可后就可以跨域訪問(wèn)POST請(qǐng)求了。一般我們會(huì)在OPTIONS的方法中加上"Allow: OPTIONS,GET,POST"類似header以區(qū)分于普通的請(qǐng)求。
|