跨域問題

文章目錄 

1. 跨域問題,解決之道

2. 解決思路

3. CORS涉及的響應頭

3.1. Access-Control-Allow-Origin

3.2. Access-Control-Allow-Methods

3.3. Access-Control-Allow-Credentials

3.4. Access-Control-Max-Age

3.5. Access-Control-Allow-Headers

4. 解決跨域問題

5. 存在問題

跨域問題,在日常開發過程中,是一個非常熟悉的名詞。之前有和大家討論過《跨域問題,解決之道》,根據讀者的反饋,希望講解具體的實現方案,因此,這週會分享一些具體的實現方案。


解決思路

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

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

CORS涉及的響應頭

Access-Control-Allow-Origin

允許訪問的客戶端域名,例如:http://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 對象中。

  1. public class CORSFilter implements Filter {
  2. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
  3. HttpServletResponse response = (HttpServletResponse) res;
  4. response.setHeader("Access-Control-Allow-Origin", "*");
  5. response.setHeader("Access-Control-Allow-Methods", "GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE, PATCH");
  6. response.setHeader("Access-Control-Max-Age", "3600");
  7. response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, Cache-control");
  8. chain.doFilter(req, res);
  9. }
  10.  
  11. public void init(FilterConfig filterConfig) {}
  12.  
  13. public void destroy() {}
  14.  
  15. }

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

  1. <filter>
  2. <filter-name>corsFilter</filter-name>
  3. <filter-class>com.lianggzone.core.filter.CorsFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>corsFilter</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

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

存在問題

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章