2

IIS のローカル インスタンスで ASP.NET Web API アプリケーションを実行しています。Web アプリケーションは CORS で構成されています。私が呼び出している Web API メソッドは次のようになります。

[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 にアクセスしている場合に問題なく動作します。

単一の要求ヘッダーを追加すると、ローカル IIS サーバーに対して次の要求が失敗します。

$.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);
    }
});

私が見る非常に詳細なログメッセージは次のとおりです。

Failure: error, 

Visual Studio 内の IIS Express 開発インスタンスに対して行うと、同じPOST要求が成功します。

Fiddler では、完全な IIS サーバーまたは Visual Studio 内の IIS Express を対象としているかどうかに関係なく、前の 2 つの要求は失敗することなく通過します。

// 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}はすべて、Fiddler 内で同一の出力を生成します。

要するに、要求ヘッダーを設定すると、ローカルの完全な IIS インスタンスに対して AJAX 呼び出しが失敗するのはなぜですか?

さらに、Fiddler ではリクエストが成功するのに、Javascript コードでは成功しないのはなぜですか? 適切な IIS インスタンスで要求ヘッダーを設定できない場合、これは深刻な問題です。

4

2 に答える 2

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/

于 2012-10-09T20:40:33.270 に答える
0

CORS の問題の実際の根本的な問題は、IIS 7 で使用されるパイプラインに関連していました。

IIS 7 がクラシック パイプラインで動作している場合、要求はOPTIONS要求と共にプリフライトされませんでした。私の質問で説明したように、それらは黙って失敗します。これは、Firebug の [ネット] タブと、ソリューションのプロジェクトとして明示的に含まれているThinktecture IdentityModelライブラリを使用したインタラクティブなデバッグで確認できました。

ただし、IIS 7 が統合パイプラインで動作する場合、CORS は尊重されます。POSTリクエストおよびカスタム ヘッダーを含むリクエストは正しくプリフライトされます。

于 2012-10-31T14:35:49.093 に答える