2017-03-02 59 views
2

一般:預檢要求

Request URL:x/site.php 
Request Method:OPTIONS 
Status Code:302 Found 
Remote Address:x.x.x.x:80 

響應頭:

view source 
Access-Control-Allow-Headers:Content-Type 
Access-Control-Allow-Origin:* 
Access-Control-Max-Age:300 
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Content-Length:0 
Content-Type:text/html; charset=UTF-8 
Date:Thu, 02 Mar 2017 14:27:21 GMT 
Expires:Thu, 19 Nov 1981 08:52:00 GMT 
Location:y 
Pragma:no-cache 
Server:Apache/2.4.25 (Ubuntu) 

請求報頭:

view source 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8 
Access-Control-Request-Headers:authorization 
Access-Control-Request-Method:POST 
Cache-Control:no-cache 
Connection:keep-alive 
DNT:1 
Host:x 
Origin:http://127.0.0.1:3000 
Pragma:no-cache 
Referer:http://127.0.0.1:3000/ 
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.90 Safari/537.36 

Apache的虛擬主機的配置看起來像這樣:

<IfModule mod_headers.c> 
      Header set Access-Control-Allow-Origin "http://127.0.0.1:3000" 
      Header set Access-Control-Allow-Origin "http://127.0.0.1" 
      Header set Access-Control-Max-Age "300" 
      Header set Access-Control-Allow-Credentials "true" 
      Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept" 
      Header set Access-Control-Allow-Methods "POST, GET, PUT, DELETE, PATCH, OPTIONS" 
    </IfModule> 

預檢請求正在跳過apache配置並直接點擊我的web應用程序,這會重定向(因此302和位置:y)。

我不知道爲什麼預檢請求沒有被Apache處理?

回答

3

兩個主要的事情,你需要更改/添加有:

  • 使用Header always set,而不是僅僅Header set
  • 使用mod_rewrite由剛剛發回200 OK與頭處理OPTIONS

所以爲了使問題中的請求起作用,下面是一個最小(ish)配置片段:

Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Allow-Headers "Authorization" 
Header always set Access-Control-Allow-Methods "GET, OPTIONS" 
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location" 
Header always set Access-Control-Max-Age "600" 

RewriteEngine On 
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L] 
https://benjaminhorn.io/code/setting-cors-cross-origin-resource-sharing-on-apache-with-correct-response-headers-allowing-everything-through/

較長的解釋是什麼值,爲各種Access-Control-響應頭設置的一般常識:

  • Access-Control-Allow-Headers:你必須將其設置爲包含任何標題名稱您的要求發送,除了CORS-safelisted header names或所謂「forbidden」 header names(由瀏覽器設置的標題名稱,您不能設置在你的JavaScript中); the spec alternatively allows the * wildcard它的價值,以便您日後嘗試,但沒有瀏覽器支持它尚未:Chrome bugFirefox bugSafari bug

  • Access-Control-Allow-Methodsthe spec alternatively allows the * wildcard - 但是再次,與Access-Control-Allow-Headers: *,沒有瀏覽器都支持它尚未

  • Access-Control-Expose-Headers:你必須設置包含任何響應頭你的客戶端代碼需要讀取超出Cache-ControlContent-LanguageContent-TypeExpires,Last-ModifiedPragma--它們默認是公開的(很多人忘了設置它,並最終因爲無法讀取特定響應頭的值而感到困惑);再次the spec alternatively allows the * wildcard這裏,但沒有瀏覽器都支持它尚未

  • Access-Control-Max-Age:鉻有600(10分鐘)的上限hardcoded,所以沒有點它比設置一個較高的值(Firefox可能尊重,但Chrome將只是阻止它下降到10分鐘,如果你設置得更高,和Safari它限制到只有分鐘)

那麼,關於這個問題所示的特定要求,這裏有一些具體說明:

  • 你的要求有Access-Control-Request-Headers:authorization所以在你的Apache配置,在Access-Control-Allow-Headers響應頭添加Authorization了。

  • Origin是「禁止入內」頭名由瀏覽器設置,並Accept是CORS-safelisted頭名,所以你並不需要將它們納入Access-Control-Allow-Headers

  • 你的請求不發送Content-Type,因此它沒有在反應中需要Access-Control-Allow-Headers(永不需要GET請求和以其他方式僅需要如果類型是比application/x-www-form-urlencodedtext/plain,或其它multipart/form-data

  • 對於Access-Control-Allow-Methods,您的要求似乎只是一個GET,所以除非你打算也使POST/PUT/DELETE/PATCH請求,沒有任何意義了明確,包括他們