跨域問題,解決方案 - CORS方案

樑桂釗發表於2016-12-12

原文地址:跨域問題,解決方案 - CORS方案
部落格地址:blog.720ui.com/

跨域問題,解決之道

連結文章:跨域問題,解決之道

解決思路

CORS 全稱為 Cross Origin Resource Sharing(跨域資源共享)。整個CORS通訊過程,都是瀏覽器自動完成,不需要使用者參與。對於開發者來說,CORS通訊與同源的AJAX通訊沒有差別,程式碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動新增一些附加的頭資訊,但使用者不會有感覺。因此,實現CORS通訊的關鍵是服務端。服務端只需新增相關響應頭資訊,即可實現客戶端發出 AJAX 跨域請求。

值得注意的是,瀏覽器必須先以 OPTIONS 請求方式傳送一個預請求,從而獲知伺服器端對跨源請求所支援 HTTP 方法。在確認伺服器允許該跨源請求的情況下,以實際的 HTTP 請求方法傳送那個真正的請求。

CORS涉及的響應頭

Access-Control-Allow-Origin

允許訪問的客戶端域名,例如:blog.720ui.com,若為星形標示號,則表示從任意域都能訪問,即不做任何限制。值得注意的是,Access-Control-Allow-Origin 只允許兩種取值,一個是星形標示號,一個是具體的域名,不支援同時配置多個域名。

Access-Control-Allow-Methods

允許訪問的方法名,多個方法名用逗號分割,例如:GET,POST,PUT,DELETE,OPTIONS。

Access-Control-Allow-Credentials

是否允許請求帶有驗證資訊,若要獲取客戶端域下的 cookie 時,需要將其設定為 true。

Access-Control-Max-Age

可以用於 CORS 相關配置的快取。

Access-Control-Allow-Headers

允許服務端訪問的客戶端請求頭,多個請求頭用逗號分割,例如:Content-Type。

解決跨域問題

首先,我們需要編寫一個 Filter,過濾所有的 HTTP 請求,將 CORS 響應頭寫入 response 物件中。

public class CORSFilter implements Filter {  
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
        HttpServletResponse response = (HttpServletResponse) res;  
        response.setHeader("Access-Control-Allow-Origin", "*");  
        response.setHeader("Access-Control-Allow-Methods",
        "GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, PATCH");  
        response.setHeader("Access-Control-Max-Age", "3600");  
        response.setHeader("Access-Control-Allow-Headers", 
        "Origin, Accept, X-Requested-With, Content-Type, 
        Access-Control-Request-Method, Access-Control-Request-Headers, 
        Authorization, Cache-control");  
        chain.doFilter(req, res);  
    }  

    public void init(FilterConfig filterConfig) {}  

    public void destroy() {}  

}複製程式碼

然後,在 web.xml 中配置 CorsFilter 的過濾器。

<filter>  
  <filter-name>corsFilter&lt;/filter-name>  
  <filter-class>com.lianggzone.core.filter.CorsFilter&lt;/filter-class>  
</filter>  
<filter-mapping>  
  <filter-name>corsFilter&lt;/filter-name>  
  <url-pattern>/*&lt;/url-pattern>  
</filter-mapping>複製程式碼

完成上面兩個步驟,即可實現跨域功能。這樣跨多個域的問題就輕鬆解決了。

存在問題

不幸的是,CORS不支援IE8、IE9,如果產品不再考慮相容IE低版本的話,可以忽略,但是如果產品需要相容目前國內還存在大量低版本的IE市場(百分之二十多),那麼這個需要慎重考慮咯。

跨域問題,解決方案 - CORS方案

(完)

更多精彩文章,盡在「服務端思維」微信公眾號!

跨域問題,解決方案 - CORS方案

相關文章