2012-11-20 29 views
5

我有一個API託管在具有與下列頭啓用CORS一個域名:跨域XHR遇事

Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: POST, GET, OPTIONS 
Access-Control-Max-Age: 1728000 

我能夠做出從hackst.com GET或POST請求,並能正常工作。鏈接:http://hackst.com/#w3SbV

從我的骨幹應用程序託管在另一個域上,GET請求正常工作。但是,當我嘗試創建並保存新的模型(即做一個POST請求)時,出現以下錯誤:

Failed to load resource: the server responded with a status of 501 (Not Implemented) http://projectwhatup.us:5000/api/posts 
XMLHttpRequest cannot load http://projectwhatup.us:5000/api/posts. Origin http://ayush.projectwhatup.us is not allowed by Access-Control-Allow-Origin. 

我的相關骨幹代碼:

var newPostData = { 
    topic : "New Post", 
    body : "new body",   
    user_id : 1, 
}; 

var newPostModel = new Post(newPostData); 
this.model.create(newPostModel); 

我甚至嘗試過採用create方法並手動創建POST請求,如下所示:

create : function(data) { 
    console.log('overriden create'); 

    $.ajax({ 
     "url" : this.url, 
     "async" : true, 
     "beforeSend" : function(obj){ 
      console.log(obj); 
     }, 
     "contentType" : 'application/json', 
     //"crossDomain" : true, // uncommenting this doesnt help either 
     "headers" : { 

     }, 
     "dataType" : 'json', 
     "type" : 'POST', 
     "data" : JSON.stringify(data), 
     "error" : function(err){ 
      console.log('new post creation failed'); 
      console.log(err); 
     }, 
     "success" : function(resp){ 
      console.log('new post created'); 
      console.log(resp); 
     } 
    }); 
} 

同樣的錯誤。

我在JSFiddle上也嘗試了一個獨立的GET請求(http://jsfiddle.net/X9cqh/5/),但即使我的骨幹應用程序可以使GET請求正常也失敗。

在這一點上,我完全無能爲力。任何提示,指針,解決方案?

+0

看着[hurl.it(http://hurl.it/hurls/1330531e4f6c2b80fe278890b412cb50c3e4857c/432866d6c733527ea02f6436de63cbfac1a9ccc5)HEAD請求到服務器,它看起來像CORS只對'支持HTTP:// ayush.projectwhatup.us' – teddybeard

+0

但是hackst.com的請求如何通過? – xbonez

+0

這是因爲請求不是由您的Web瀏覽器進行的。類似Hurl.it,當你創建一個黑客。com請求,它由服務器在後端執行,然後在Web瀏覽器中顯示結果。 – teddybeard

回答

6

服務器還應該具有以下標題回覆預檢:

Access-Control-Allow-Headers: Content-Type 

這是必要的,因爲內容類型是application/JSON,這是在CORS規範中定義的可接受的值的範圍之外(HTTP: //www.w3.org/TR/cors/)。

+0

我們已經添加了Access-Control-Allow-Headers:Content-Type和Access-Control-Allow-Headers:Content-Type,X-Requested-With(不是兩個都是相同的時間)發送到服務器,但在發出請求時指定「內容類型」會導致請求失敗。 – xbonez

+1

你是什麼意思的「或 - 」?您應該在標題中包含所有這些值。 – monsur

+0

哦,是的,男人!我帶着這個麻煩浪費了2天時間。謝謝! –

1

您的服務器設置有效。的jsfiddle顯然不會使Ajax請求,但你可以快速測試,它的工作原理是在進入這四行Chrome的控制檯或Safari開發者控制檯:

var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'http://projectwhatup.us:5000/api/posts', false); 
xhr.send(); 
xhr.responseText; 

enter image description here

如果你試試這個用域不允許CORS,它會出錯。

+0

找出將Content-Type:application/json添加到請求原因CORS失敗。沒有它,ajax調用正在工作(http://jsfiddle.net/X9cqh/11/)問題是當發出一個POST請求時,API需要這個頭文件集或它用'400 Bad Request'響應代碼 – xbonez

+0

代碼在這個答案中不會觸發預檢(沒有額外的頭文件和使用簡單的方法GET),這就是爲什麼它似乎工作。 – kybernetikos

1

添加'Content-Type'標頭會導致CORS請求失敗的原因是您的服務器設置錯誤。

如果客戶端希望指定特定的頭文件或使用不尋常的http方法動詞(例如PUT),那麼瀏覽器將首先執行'預檢'OPTIONS調用以確保允許它設置這些頭文件。你的服務器需要用適當的頭文件來響應這個OPTIONS調用。如果您想確認問題出在哪裏,您會看到Chrome瀏覽器開發人員工具或螢火蟲的網絡選項卡中會顯示選項。

你可能會感興趣我的更詳細的解答here