2つのVSプロジェクトがあります。1つはMVC5コントローラーを公開し、もう1つはangularクライアントです。 angularクライアントがコントローラーを照会できるようにします。私は多数のスレッドを読み、次のことを試しました:
これをサーバーのWeb構成に追加しました。
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<system.webServer>
コントローラーのアクションで次のフィルターを作成して使用しました。
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
angularクライアントで、次のインターセプターを作成しました。
app.factory("CORSInterceptor", [
function()
{
return {
request: function(config)
{
config.headers["Access-Control-Allow-Origin"] = "*";
config.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
config.headers["Access-Control-Allow-Headers"] = "Content-Type";
config.headers["Access-Control-Request-Headers"] = "X-Requested-With, accept, content-type";
return config;
}
};
}
]);
app.config(["$httpProvider", function ($httpProvider) {
$httpProvider.interceptors.Push("CORSInterceptor");
}]);
Firebugによると、これにより次のリクエストが発生します。
OPTIONS //Login/Connect HTTP/1.1
Host: localhost:49815
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://localhost:50739
Access-Control-Request-Method: POST
Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-Origin,content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
そして、次の応答:
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/10.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-SourceFiles: =?UTF-8?B?RDpcVEZTXElVV2ViXEdhcE5ldFNlcnZlclxBU1BTZXJ2aWNlc1xMb2dpblxDb25uZWN0?=
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Request-Headers: X-Requested-With, accept, content-type
Date: Tue, 01 Sep 2015 13:05:23 GMT
Content-Length: 0
それでも、Firefoxは次のメッセージでリクエストをブロックします:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:49815//Login/Connect. (Reason: missing token 'access-control-allow-headers' in CORS header 'Access-Control-Allow-Headers' from CORS preflight channel).
多くの場合、私が読んだスレッドはいくつかの不必要な構成手順を提案していたため、混乱が生じました。実際には非常に簡単です...
クロスサイトリクエストを送信するという単純な目的のために、angularクライアントから、ASPコントローラへ:
唯一の必須の変更は、これをサーバーのweb.configに追加することです
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
</customHeaders>
</httpProtocol>
</system.webServer>
問題は、一部のブラウザは*
のAccess-Control-Allow-Headers
ワイルドカードをまだ許可していないことです。具体的には、Firefox 69以前はサポートしていません。 https://bugzilla.mozilla.org/show_bug.cgi?id=1309358 を参照してください。
したがって、すべてのブラウザで期待される動作を得るために、返されるAccess-Control-Allow-Headers
値には、フロントエンドコードから実際にアクセスする必要があるすべてのヘッダー名を明示的にリストする必要があります。例:質問の場合:Access-Control-Allow-Headers: Content-Type
。
すべてのヘッダー名をハードコードすることなくそれを実現する方法は次のとおりです。ブラウザが送信するAccess-Control-Request-Headers
リクエストヘッダーの値をサーバーサイドコードに取得させ、サーバーが送信するAccess-Control-Allow-Headers
レスポンスヘッダーの値にそれをエコーしますバック。
または、既存のライブラリを使用して、サーバーをCORS対応にします。 Access-Control-Request-Headers
request-headerの値をAccess-Control-Allow-Headers
response-headerの値に反映することは、ほとんどのCORSライブラリが通常行うことです。