CORS 跨域 access-control-allow-headers 的問題

原鏈接地址: http://blog.csdn.net/badboyer/article/details/51261083


CORS 跨域 access-control-allow-headers 的問題

最近項目裏需要處理跨域請求,遇到了一些問題,中間走了很多坑,深挖了很多細節,受益良多。

cors在跨域解決方案中算是很好用的,網上資料一大堆,只需要在服務器端進行配置即可。

配置方法網上也很多,我簡單記錄下,

主要用到cors-filter-1.7.jar 和java-property-utils-1.9.jar 這兩個jar包,其實cors-filter jar包最新的已經出到2.5了

不過1.7的也能用。然後在web.xml裏面配置一個filter

[html] view plain copy
  1. <span style="white-space:pre">    </span><filter>  
  2.         <filter-name>CORS</filter-name>  
  3.         <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>  
  4.         <init-param>  
  5.             <param-name>cors.allowOrigin</param-name>  
  6.             <param-value>*</param-value>  
  7.         </init-param>  
  8.         <init-param>  
  9.             <param-name>cors.supportedMethods</param-name>  
  10.             <param-value>GET, POST, HEAD, PUT, DELETE</param-value>  
  11.         </init-param>  
  12.         <init-param>  
  13.             <param-name>cors.supportedHeaders</param-name>  
  14.             <param-value>Accept, Origin, XRequestedWith, Content-Type, LastModified</param-value>  
  15.         </init-param>  
  16.         <init-param>  
  17.             <param-name>cors.exposedHeaders</param-name>  
  18.             <param-value>SetCookie</param-value>  
  19.         </init-param>  
  20.         <init-param>  
  21.             <param-name>cors.supportsCredentials</param-name>  
  22.             <param-value>true</param-value>  
  23.         </init-param>  
  24.     </filter>  
  25.     <filter-mapping>  
  26.         <filter-name>CORS</filter-name>  
  27.         <url-pattern>/*</url-pattern>  
  28.     </filter-mapping>  

普通的ajax請求測試時沒有問題的,但是 我在上傳文件跨域的時候遇到個莫名其妙的問題,用chrome上傳不好使,用firefox好使。 我

配置的沒有問題,代碼也沒什麼問題,那麼我猜測問題可能是瀏覽器的。 通過開發工具抓包,我發現chrome的請求內容是這樣的



下面的是firefox的


可以看到chrome瀏覽器多了個access-control-allow-headers 頭,而firefox則沒有。通過Fiddler模擬請求,發現就是這個

屬性的問題,去掉的話,就能發送成功。 我又上cors的官網,找到了這麼個圖片





cors過濾器的過濾流程清晰易懂,看起來還是挺好理解的,後來我又查看了源碼,發現在判斷access-control-allow-headers頭的時候會根據xml裏面cors.supportedHeaders配置的進行比對,如果這個頭沒有配置就返回403,我配置了,但是和瀏覽器配置的不一樣我配置的是ContentType,但瀏覽器發送的是Content-Type,多了個橫槓 快哭了,看起來一個小問題,水卻很深啊。  在上圖中可以看到,會先判斷是不是帶origin頭,如果帶的話,纔會判斷access-control-allow-headers頭,這是個自定義的頭信息。

在調試的過程中發現springmvc 默認是不支持options 請求, 要想支持這個請求,需要在web.xml的DispatcherServlet 增加
        <init-param>
            <param-name>dispatchOptionsRequest</param-name>
            <param-value>true</param-value>
        </init-param>
同時,在RequestMapping中需要知道method是options的,這樣springmvc就可以接收到options請求。
options請求比較特殊,是個透明請求,一般在跨域的時候瀏覽器會先發個options請求,詢問服務器是否支持跨域, access-control-allow-method表示後面實際發送數據的請求方法, 這個方法名需要包含在cors.supportedMethods 的配置。


CORS可以分成兩種:

  • 簡單請求
  • 複雜請求

一個簡單的請求大致如下:

  • HTTP方法是下列之一
    • HEAD
    • GET
    • POST
  • HTTP頭包含
    • Accept
    • Accept-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type,但僅能是下列之一
      • application/x-www-form-urlencoded
      • multipart/form-data
      • text/plain

任何一個不滿足上述要求的請求,即被認爲是複雜請求。一個複雜請求不僅有包含通信內容的請求,同時也包含預請求(preflight request)。



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