私はこの記事に書かれていることをすべて試してみました: http://www.asp.net/web-api/overview/security/enabling-cross-Origin-requests-in-web-api 、しかし何も動作しません。私はAngularJSを使用してwebAPI2(MVC5)から別のドメインで使用するためのデータを取得しようとしています。
私のコントローラーはこんな感じです:
namespace tapuzWebAPI.Controllers
{
[EnableCors(origins: "http://local.tapuz.co.il", headers: "*", methods: "*", SupportsCredentials = true)]
[RoutePrefix("api/homepage")]
public class HomePageController : ApiController
{
[HttpGet]
[Route("GetMainItems")]
//[ResponseType(typeof(Product))]
public List<usp_MobileSelectTopSecondaryItemsByCategoryResult> GetMainItems()
{
HomePageDALcs dal = new HomePageDALcs();
//Three product added to display the data
//HomePagePromotedItems.Value.Add(new HomePagePromotedItem.Value.FirstOrDefault((p) => p.ID == id));
List<usp_MobileSelectTopSecondaryItemsByCategoryResult> items = dal.MobileSelectTopSecondaryItemsByCategory(3, 5);
return items;
}
}
}
Web ApiでCORSを有効にする必要があります。 CORSをグローバルに有効にするためのより簡単で好ましい方法は、web.configに以下を追加することです。
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
</system.webServer>
*
を使用する代わりに、メソッドがすべて個別に指定されていることに注意してください。これは*
を使用するときにバグが発生するためです。
コードでCORSを有効にすることもできます。
更新
次のNuGetパッケージが必要です:Microsoft.AspNet.WebApi.Cors
。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors();
// ...
}
}
そうすると、アクションやコントローラで[EnableCors]
属性を使うことができます。
[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
またはあなたはそれをグローバルに登録することができます
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("http://www.example.com", "*", "*");
config.EnableCors(cors);
// ...
}
}
また、プリフライトOptions
要求をHTTP OPTIONS
要求で処理する必要があります。
Web API
はOptions
をサポートするように設定されていることを確認するためにCORS
リクエストに応答する必要があります。
これを処理するために、あなたがする必要があるのは空の応答を送り返すことだけです。あなたの行動の中でこれを行うことができますか、またはこのようにグローバルにそれを行うことができます:
# Global.asax.cs
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
この追加のチェックは、APIs
およびGET
要求のみを受け入れるように設計された古いPOST
が悪用されないようにするために追加されました。この動詞が存在しないときに設計されたDELETE
にAPI
要求を送信するとします。結果は予測不能であり、結果は危険になる可能性があります。
@ Mihai-Andrei Dinculescuの答えは正しいですが、検索者のためにこのエラーを引き起こす可能性がある微妙な点もあります。
URLの末尾に「/」を追加すると、EnableCorsがすべての場合(たとえばホームページから)で機能しなくなります。
すなわちこれはうまくいきません
var cors = new EnableCorsAttribute("http://testing.azurewebsites.net/", "*", "*");
config.EnableCors(cors);
しかしこれはうまくいきます:
var cors = new EnableCorsAttribute("http://testing.azurewebsites.net", "*", "*");
config.EnableCors(cors);
EnableCors属性を使用した場合の効果は同じです。
私はMihai-Andrei Dinculescuによって示された上記のすべてのステップに従った。
しかし私の場合、http OPTIONSが以下の行によってWeb.Configで無効にされているので、私はもう1つもう1つステップを必要としました。
<remove name="OPTIONSVerbHandler" />
私はちょうどWeb.Configからそれを削除しました(ちょうどそれを以下のようにコメントしてください)そしてCorsは魅力のように働きます
<handlers>
<!-- remove name="OPTIONSVerbHandler" / -->
</handlers>
Cors nuget packagesのインストールが原因かもしれません。
あなたがnugetからCorsをインストールして有効にした後で問題に直面しているなら、あなたはWeb Apiを再インストールすることを試みるかもしれません。
パッケージマネージャから、Update-Package Microsoft.AspNet.WebApi -reinstall
を実行します。
これを試して、CORSが正しく構成されていることを確認してください。
[EnableCors(origins: "*", headers: "*", methods: "*")]
まだ動かない? HTTPヘッダーの存在を確認してください。
CORSプロトコルを機能させるには、すべてのエンドポイントにOPTIONSメソッド(またはこのメソッドを持つグローバルフィルタ)を用意して、これらのヘッダを返す必要があります。
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type
これは、ブラウザが最初にOPTIONSリクエストを送信してサーバーを「テスト」して承認を確認するためです。
@ Mihai-Andrei Dinculescuの回答が私に役に立ちました。
<httpProtocol>
セクションに<system.webServer>
を追加するglobal.asax
内の言及されたApplication_BeginRequest()
を介してOPTIONS
リクエストに対して空のレスポンスを返すリクエストにoriging
が含まれていたため、小文字で、Request.Headers.AllKeys.Contains("Origin")
に対する彼のチェックが私にはうまくいきませんでした。私のブラウザ(Chrome)はCORSリクエストに対してこのように送信すると思います。
代わりに 大文字と小文字を区別しない 変種のContains
チェックを使用することで、これをもう少し一般的に解決しました:if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {
私はこれに非常に遅れて来ていることを知っています。しかし、検索している人にとっては、私が最終的に私のために働いたものを公開すると思いました。私はそれが最善の解決策だと主張しているわけではありません。
WebApiサービスはconfig.EnableCors(corsAttribute)メソッドを使用します。ただし、それでも、プリフライトリクエストでは失敗します。 @ Mihai-Andrei Dinculescuの答えは私に手がかりを提供しました。まず、オプション要求をフラッシュするために彼のApplication_BeginRequest()コードを追加しました。それでもそれは私にとってはうまくいきませんでした。問題は、WebAPIがOPTIONS要求に予想されるヘッダーをまだ追加していないことです。それだけをフラッシュしてもうまくいきませんでした-しかし、それは私にアイデアを与えました。そうでなければweb.configを介してOPTIONS要求の応答に追加されるカスタムヘッダーを追加しました。これが私のコードです:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Headers.Add("Access-Control-Allow-Origin", "https://localhost:44343");
Response.Headers.Add("Access-Control-Allow-Headers",
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
Response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
Response.Headers.Add("Access-Control-Allow-Credentials", "true");
Response.Flush();
}
}
明らかに、これはOPTIONSリクエストにのみ適用されます。他のすべての動詞は、CORS構成によって処理されます。これに対するより良いアプローチがあれば、私はすべて耳です。私にはごまかしのような感じで、ヘッダーが自動的に追加された方がいいと思いますが、これが最終的に機能し、先へ進むことができました。
私はコアについて次のケースを捉えます。たぶんそれは誰かに役立つでしょう。サーバーに機能「WebDavリダイレクター」を追加した場合、PUT要求とDELETE要求は失敗します。
そのため、IISサーバーから「WebDAVModule」を削除する必要があります。
またはあなたの設定に追加します。
<system.webServer>
<modules>
<remove name="WebDAVModule"/>
</modules>
<handlers>
<remove name="WebDAV" />
...
</handlers>
私はこの答えで与えられた方法を含む私がネットで見つけることができるすべてを試みました。一日中問題を解決しようと試みた後、私は魅力のように私のために働いていた解決策を見つけました。
フォルダApp_StartのファイルWebApiConfigで、コードのすべての行をコメントアウトして、次のコードを追加します。
`public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
var enableCorsAttribute = new EnableCorsAttribute("*",
"Origin, Content-Type, Accept",
"GET, PUT, POST, DELETE, OPTIONS");
config.EnableCors(enableCorsAttribute);
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
//routeTemplate: "api/{controller}/{id}",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Formatters.Add(new BrowserJsonFormatter());
}
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SerializerSettings.Formatting = Formatting.Indented;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}`
次のようにweb.configにsecurity\requestFilteringノードがあるとします。
<security>
<requestFiltering>
<verbs allowUnlisted="false">
<add verb="GET" allowed="true" />
<add verb="POST" allowed="true" />
<add verb="PUT" allowed="true" />
<add verb="DELETE" allowed="true" />
<add verb="DEBUG" allowed="true" />
</verbs>
</requestFiltering>
必ずこれも追加してください
<add verb="OPTIONS" allowed="true" />