2012-10-09 74 views
2

我有一個ASP.NET Web API應用程序運行在我的本地IIS實例上。 Web應用程序使用CORS進行配置。在Web API方法我打電話讀取類似:AJAX請求失敗時設置標題,但沒有它們成功

[POST("/API/{foo}/{bar}")] 
public String DoSomething(String foo, String bar) 
{ 
    return "Hello, World!"; 
} 

客戶端,我運行以下請求:

$.ajax({ 
    url: "http://machine/API/Foo/Bar", 
    type: "POST", 
    success: function (data) { 
     console.log("Success: " + data); 
    }, 
    error: function (xhr, status, message) { 
     console.log("Failure: " + status + ", " + message); 
    } 
}); 

的Firefox 15.0.1中的相應控制檯日誌全文:

test.html (line 38) 
POST http://machine/API/Foo/Bar 

200 OK 
     112ms 
jquery-1.7.2.js (line 8240) 

Success: "Hello, World!" 

當我訪問我的本地IIS服務器時以及在Visual Studio中訪問IIS Express開發實例的相應URL時,此功能完美無瑕。

$.ajax({ 
    url: "http://machine/API/Foo/Bar", 
    type: "POST", 
      onBeforeSend: function (xhr, settings) { 
       xhr.setRequestHeader("A", "B"); 
      }, 
    success: function (data) { 
     console.log("Success: " + data); 
    }, 
    error: function (xhr, status, message) { 
     console.log("Failure: " + status + ", " + message); 
    } 
}); 

不斷如此詳細的日誌消息,我看到的是::

當我添加一個請求頭,任何東西,下面的請求時對我的本地IIS服務器做出失敗

Failure: error, 

同樣的POST在Visual Studio中針對IIS Express開發實例進行的請求是成功的。

在提琴手,前兩次請求都通過無故障,無論我是否針對Visual Studio中的完整的IIS服務器或IIS快遞:

// Request 
POST http://machine/Foo/Bar HTTP/1.1 
Host: machine 
Content-Length: 0 

// Response 
HTTP/1.1 200 OK 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Length: 38 
Content-Type: application/json; charset=utf-8 
Expires: -1 
Server: Microsoft-IIS/7.5 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Tue, 09 Oct 2012 20:16:29 GMT 

"Hello, World!" 

的排列{With Headers, Without Headers} x {Full IIS, IIS Express}都產生內提琴手相同的輸出。

簡而言之:爲什麼設置請求標頭會導致AJAX調用對我的本地完全成熟的IIS實例失敗?

此外,爲什麼我的請求在Fiddler中成功,但不是在我的Javascript代碼中?如果我無法在適當的IIS實例中設置請求標頭,這是一個嚴重的問題。

+0

什麼是你通過所有這些方法?這應該是您收到您的成功(200)/失敗(500?)響應代碼的地方。你有沒有試過簡單地將這些值傳入一個始終以狀態碼200和真的響應的服務? – Jared

+0

我設置了IIS Express和完整的IIS以在正在調用的Web API函數處設置斷點。當斷點失敗並出現Failure:error消息時,斷點不會被命中,它在IIS Express中調試時或在完整的IIS中沒有請求頭時會得到命中。 –

回答

0

我CORS問題的實際潛在問題涉及由IIS使用的管道7

當IIS 7的經典管道下運行,請求並沒有被預檢與OPTIONS請求。正如我在我的問題中所描述的,他們會默默地失敗。我在Firebug的Net選項卡中看到了這一點,並通過交互式調試將Thinktecture IdentityModel庫作爲項目明確包含在我的解決方案中。

但是,當IIS 7在Integrated Pipeline下運行時,CORS受到尊重。 POST具有自定義標頭的請求和請求已正確預檢。

1

這可能與跨源數據共享有關。在最近的一個項目中,我們碰到了類似的東西,並且與自定義http頭交叉源數據共享成了問題。

這應該只發生如果JavaScript的域是不同的比正在進行的ajax調用的域。

要確定是否是這種情況,你可以嘗試把類似這樣的東西在您的Global.asax:

protected void Application_BeginRequest(object sender, EventArgs e) 
{ 
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
    { 
     //These headers will handle the HTTP OPTIONS call sent by the browser 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods" , "GET, POST"); 
     HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "A, Foo, Bar"); 
     HttpContext.Current.Response.End(); 
    } 
} 

注意警惕做這樣的事情的。將Access-Control-Allow-Origin標頭設置爲「*」值是一種安全風險。

的輔助材料: http://www.w3.org/TR/cors/

+0

我已經通過CORS支持ASP進行了此設置。 NET Web API。策略設置爲允許所有源的所有資源都等同於所有資源:'cors.ForAllResources()。ForAllOrigins()。AllowAll();' –

+0

重要的訪問控制標題對於您將是'訪問控制 - 允許 - 頭部「選項請求的響應頭部,告訴瀏覽器哪些頭部可以從你的域發送到這個IIS實例。什麼是OPTIONS請求的實際響應? – Trinima