我們開發H5專案,透過JS呼叫某個遠端介面時經常會出現這跨域的問題,一般的解決辦法就是在伺服器增加對請求頭的判斷。
這裡我們講一下在java中透過filter過濾器如何實現;當然,你也可以在nginx中配置,或者使用jsonp實現。
1、假如我命名為:CorsFilter.java
public class CorsFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; res.setContentType("application/json;charset=UTF-8"); res.setHeader("Access-Control-Allow-Origin", "*"); res.setHeader("Access-Control-Allow-Methods", "POST, GET"); res.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type"); res.setHeader("Access-Control-Max-Age", "604800"); chain.doFilter(request, response); /* 跨域配置說明 * Access-Control-Allow-Origin 設定允許跨域的白名單,在白名單裡的跨域請求是允許的。 * Access-Control-Allow-Methods 設定接受的方法,這裡只接受POST方法。 * Access-Control-Allow-Headers 設定接受的請求頭,用逗號分隔。 * Access-Control-Allow-Max-Age 設定預檢的有效期,單位為秒。傳送正式請求前,瀏覽器會預先傳送一個預檢請求,如果伺服器返回了上述資訊,表明是可以跨越請求的,然後才會正式傳送請求。預檢成功後,在有效期內就不用再傳送了。 * Access-Control-Allow-Credentials 設定是否允許客戶端攜帶驗證資訊 */ } @Override public void destroy() { // TODO Auto-generated method stub } }
這裡我們提一下:Access-Control-Allow-Origin 這個配置,他是表示允許的白名單,“ * ” 表示不限。
這是一種比較粗暴的設定,容易引起DDOS攻擊,所以,最好還是進行指定域名,如:Access-Control-Allow-Origin: "http://www.domain.com/"
但是,如果有多個域名怎麼辦?這裡需要做一下判斷,動態賦一下值。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse res = (HttpServletResponse) response; String[] allowDomain = {"http://www.domain1.com", "http://www.domain2.com"}; Set<String> allowedOrigins = new HashSet<String>(Arrays.asList(allowDomain)); String originHeader = ((HttpServletRequest) request).getHeader("Origin"); if (allowedOrigins.contains(originHeader)) { res.setHeader("Access-Control-Allow-Origin", originHeader); res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); res.setHeader("Access-Control-Max-Age", "3600"); res.setHeader("Access-Control-Allow-Headers", "content-type, x-requested-with"); res.setHeader("Access-Control-Allow-Credentials", "true"); } chain.doFilter(request, response); }
2、在web.xml中配置如下
<!-- 跨域過濾器 --> <filter> <filter-name>cors</filter-name> <filter-class>com.domian.controller.filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>cors</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>