1. 程式人生 > >Java服務端 CORS 跨域配置

Java服務端 CORS 跨域配置

現在的web程式架構越來越趨向於前後端分離,前後端分離的好處,這裡就不再說了。但面臨的問題就有一個,那就是跨域的問題。這裡簡單記錄一下服務端這邊的解決方案。

外部jar包實現

maven 加入依賴:

  <dependency>  
      <groupId>com.thetransactioncompany</groupId>  
      <artifactId>java-property-utils</artifactId>  
      <version>1.7.1</version>  
  </dependency>  
  <dependency>  
      <groupId>com.thetransactioncompany</groupId>  
      <artifactId>cors-filter</artifactId>  
      <version>2.5</version>  
  </dependency>  

web.xml中配置:

    <filter>
        <description>跨域過濾器</description>
        <filter-name>CORS</filter-name>
        <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
        <init-param>
            <param-name>cors.allowOrigin</param-name>
            <param-value>*</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedMethods</param-name>
            <param-value>GET, POST, HEAD, PUT, DELETE, OPTIONS</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportedHeaders</param-name>
            <param-value>Accept, Origin, X-Requested-With, Content-Type, fuserkey</param-value>
        </init-param>
        <init-param>
            <param-name>cors.exposedHeaders</param-name>
            <param-value>Set-Cookie</param-value>
        </init-param>
        <init-param>
            <param-name>cors.supportsCredentials</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CORS</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

自定義Filter實現

這裡使用的是基於 servlet 3.0 註解方式配置Filter,需要servlet 3.0, tomcat 7及以上的才有此包。相關基於註解方式配置Filter,Servlet 自行百度。

import org.apache.commons.lang3.StringUtils;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 跨域過濾器
 *
 * 基於 servlet 3.0 註解方式配置Filter
 * 需要servlet 3.0, tomcat 7及以上的才有此包.
 * 多個filter的執行順序,通過類名排序.
 *
 * @author yanfa.Chen
 * @date 2017/12/1
 */

@WebFilter(filterName = "corsFilter", value = {"*.do"})
public class CorsFilter implements Filter {
    /*
    Access-Control-Allow-Origin:允許訪問的客戶端域名,例如:http://web.xxx.com,若為*,則表示從任意域都能訪問,即不做任何限制;
    Access-Control-Allow-Methods:允許訪問的方法名,多個方法名用逗號分割,例如:GET,POST,PUT,DELETE,OPTIONS;
    Access-Control-Allow-Credentials:是否允許請求帶有驗證資訊,若要獲取客戶端域下的cookie時,需要將其設定為true;
    Access-Control-Allow-Headers:允許服務端訪問的客戶端請求頭,多個請求頭用逗號分割,例如:Content-Type;
    Access-Control-Expose-Headers:允許客戶端訪問的服務端響應頭,多個響應頭用逗號分割。
    */

    /**
     * 允許的請求源,預設為所有。
     * 如果需要配置為允許多個域名,則可以採用陣列形式,如果當前請求的origin 包含在白名單中就設定該域名到origin中。
     */
    private final String allowOrigin = "*";
    /**
     * 允許請求的方法
     */
    private final String allowMethods = "GET,POST,PUT,DELETE,OPTIONS";
    private final String allowCredentials = "true";
    private final String allowHeaders = "Accept, Origin, X-Requested-With, Content-Type, fuserkey";
    private final String exposeHeaders = "Set-Cookie";

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;

        String currentOrigin = request.getHeader("Origin");

        if(StringUtils.isNotEmpty(allowOrigin)){
            response.setHeader("Access-Control-Allow-Origin", allowOrigin);
        }

        response.setHeader("Access-Control-Allow-Methods", allowMethods);
        response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
        response.setHeader("Access-Control-Allow-Headers", allowHeaders);
        response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
        chain.doFilter(req, resp);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        System.out.println("CorsFilter 啟動了");
    }

}