2016-11-08 68 views
4

我試圖從我的angular.js應用程序向我的服務器發送一些HTTP請求,但是我需要解決一些cors錯誤。來自angular的HTTP請求將使用方法OPTIONS而不是POST發送

HTTP請求是等於該樣品:

functions.test = function(foo, bar) { 
    return $http({ 
     method: 'POST', 
     url: api_endpoint + 'test', 
     headers: { 
      'foo': 'value', 
      'content-type': 'application/json' 
     }, 
     data: { 
      bar:'value' 
     } 
    }); 
}; 

在第一次嘗試端與一些CORS錯誤。所以,我實現了以下行我的PHP服務器腳本:

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); 
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type'); 

的第一個錯誤,現在被消除。

現在開發者控制檯(在Chrome)告訴我以下錯誤:

angular.js:12011個OPTIONS http://localhost:8000/test(匿名 功能)

423ef03a:1的XMLHttpRequest不能加載 http://localhost:8000/test。預檢響應具有無效的HTTP 狀態碼400

和網絡請求看起來像我預期的(狀態400還預計):

network request

我無法想象如何解決(以及如何理解)爲什麼請求將作爲OPTIONS在本地主機上發送,並作爲POST發送到遠程服務器。有沒有解決方法如何解決這個奇怪的事情?

+1

嘗試在標頭中添加'Accept':'application/json' –

+2

OPTIONS是由瀏覽器發送的預檢請求,因爲POST調用中設置了自定義標頭;這是正常的。 我認爲問題是與這些標題的內容。 –

+2

問題在於對預檢('OPTIONS')請求的響應不成功,即HTTP 400.這就是爲什麼真實(跟隨)請求失敗。您必須確保對預檢請求的響應是有效的。 –

回答

3

OPTIONS請求被稱爲pre-flight request,它是Cross-origin resource sharing (CORS)的一部分。瀏覽器使用它來檢查是否允許來自特定域的真正請求(在成功的情況下將遵循)。

瀏覽器要發送的預飛行在這些情況下請求:

  • 定製HTTP頭像application/xmlapplication/json等,使用
  • 請求方法以外GETHEADPOSTPOST方法是另一種內容類型比application/x-www-form-urlencoded,multipart/form-datatext/plain

您需要確保到飛行前請求的響應具有以下屬性

  • 成功的HTTP狀態代碼,即200 OK
  • Access-Control-Allow-Origin: **允許來自任何域的請求,則可以使用任何特定的域在這裏限制訪問的過程)

從另一面,服務器可以拒絕CORS請求簡單地通過發送到飛行前請求具有以下屬性的響應:

  • 非成功HTTP代碼(即,比其它2XX
  • 成功HTTP代碼(例如200 OK),但沒有任何CORS頭(即Access-Control-Allow-*

所以,你的情況,正確的頭文件是存在,你只需要確保飛行前響應的HTTP狀態代碼200 OK

有關詳細信息,請參閱documentation on Mozilla Developer Network或例如HTML5Rocks' CORS tutorial

0

我遇到了編寫Angular 2應用程序的非常類似的問題 - 它使用NODE服務器作爲API。

由於我在本地機器上開發,當我嘗試從我的Angular應用程序POST到API時,我不斷收到Cross Origin Header問題。

如下所示設置Headers(在節點服務器中)適用於GET請求,但我的PUT請求一直將空對象發佈到數據庫。

header('Access-Control-Allow-Origin: *'); 
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT'); 
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, 
Origin, Authorization, Accept, Client-Security-Token, Accept- 
Encoding, X-Auth-Token, content-type'); 

閱讀Dawid Ferenczy's post後,我意識到,預檢要求是空白的數據發送到我的服務器,這就是爲什麼我的數據庫條目是空的,所以我說這條線在節點JS服務器:

if (req.method == "OPTIONS") 
    { 
     res.writeHead(200, {"Content-Type": "application/json"}); 
     res.end(); 
    } 

所以現在我的服務器忽略了PREFLIGHT請求(並且返回狀態200,讓瀏覽器知道所有事情都是常規的...),那樣的話,真正的請求可以通過並且我得到真實的數據發佈到我的數據庫!

相關問題