http://enable-cors.org/server_aspnet.html の手順に従って、RESTful API(ASP.NET WebAPI2で実装)がクロスオリジンリクエスト(CORS有効)で動作するようにしました。 web.configを変更しない限り機能しません。
WebApi Cors依存関係をインストールしました:
install-package Microsoft.AspNet.WebApi.Cors -ProjectName MyProject.Web.Api
次に、App_Start
に次のようにクラスWebApiConfig
があります。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
var constraintsResolver = new DefaultInlineConstraintResolver();
constraintsResolver.ConstraintMap.Add("apiVersionConstraint", typeof(ApiVersionConstraint));
config.MapHttpAttributeRoutes(constraintsResolver);
config.Services.Replace(typeof(IHttpControllerSelector), new NamespaceHttpControllerSelector(config));
//config.EnableSystemDiagnosticsTracing();
config.Services.Replace(typeof(ITraceWriter), new SimpleTraceWriter(WebContainerManager.Get<ILogManager>()));
config.Services.Add(typeof(IExceptionLogger), new SimpleExceptionLogger(WebContainerManager.Get<ILogManager>()));
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
}
}
しかし、その後、アプリケーションを実行し、次のようなFiddlerでリソースを要求します。 http:// localhost:51589/api/v1/persons そして応答では、表示されるはずのHTTPヘッダーが表示されませんといった:
Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS
Access-Control-Allow-Origin: *
ステップがありませんか?コントローラーで次の注釈を試しました。
[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]
同じ結果、CORSは有効になりません。
ただし、web.configに以下を追加すると(AspNet.WebApi.Cors依存関係をインストールしなくても)動作します:
<system.webServer>
<httpProtocol>
<!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
<!--
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, Origin, X-Requested-With, Authorization, name" />
<add name="Access-Control-Allow-Credentials" value="true" />
</customHeaders>
-->
</httpProtocol>
<handlers>
<!-- THESE HANDLERS ARE IMPORTANT FOR WEB API TO WORK WITH GET,HEAD,POST,PUT,DELETE and CORS-->
<!--
<remove name="WebDAV" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,PUT,DELETE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
-->
</handlers>
どんな助けも大歓迎です!
ありがとうございました。
簡略化されたデモプロジェクトを作成しました。
上記のAPI LinkをローカルFiddlerから試して、ヘッダーを確認できます。ここに説明があります。
これはすべてWebApiConfig
を呼び出すだけです。それはコード編成に他なりません。
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
WebApiConfig.Register(GlobalConfiguration.Configuration);
}
}
ここでの重要なメソッドはEnableCrossSiteRequests
メソッドです。これはallする必要があります。 EnableCorsAttribute
は グローバルスコープのCORS属性 です。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
EnableCrossSiteRequests(config);
AddRoutes(config);
}
private static void AddRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/"
);
}
private static void EnableCrossSiteRequests(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
origins: "*",
headers: "*",
methods: "*");
config.EnableCors(cors);
}
}
Get
メソッドは、グローバルに適用したEnableCors
属性を受け取ります。 Another
メソッドは、グローバルEnableCors
をオーバーライドします。
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] {
"This is a CORS response.",
"It works from any Origin."
};
}
// GET api/values/another
[HttpGet]
[EnableCors(origins:"http://www.bigfont.ca", headers:"*", methods: "*")]
public IEnumerable<string> Another()
{
return new string[] {
"This is a CORS response. ",
"It works only from two origins: ",
"1. www.bigfont.ca ",
"2. the same Origin."
};
}
}
Web.configに特別なものを追加する必要はありません。実際、これはデモのweb.configの外観です-空です。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
</configuration>
var url = "https://cors-webapi.azurewebsites.net/api/values"
$.get(url, function(data) {
console.log("We expect this to succeed.");
console.log(data);
});
var url = "https://cors-webapi.azurewebsites.net/api/values/another"
$.get(url, function(data) {
console.log(data);
}).fail(function(xhr, status, text) {
console.log("We expect this to fail.");
console.log(status);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
いくつかのファイルを変更するだけです。これは私のために動作します。
Global.ascx
public class WebApiApplication : System.Web.HttpApplication {
protected void Application_Start()
{
WebApiConfig.Register(GlobalConfiguration.Configuration);
} }
WebApiConfig.cs
すべてのリクエストはこのコードを呼び出す必要があります。
public static class WebApiConfig {
public static void Register(HttpConfiguration config)
{
EnableCrossSiteRequests(config);
AddRoutes(config);
}
private static void AddRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "Default",
routeTemplate: "api/{controller}/"
);
}
private static void EnableCrossSiteRequests(HttpConfiguration config)
{
var cors = new EnableCorsAttribute(
origins: "*",
headers: "*",
methods: "*");
config.EnableCors(cors);
} }
一部のコントローラー
変更するものはありません。
Web.config
web.configにハンドラを追加する必要があります
<configuration>
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
</configuration>
CORSリクエストの場合、最新のブラウザはすべてOPTION動詞で応答し、その後、実際のリクエストが続きます。これは、CORS要求の場合にユーザーに確認を求めるために使用されることになっています。ただし、APIの場合、この検証プロセスをスキップする場合は、Global.asaxに次のスニペットを追加します
protected void Application_BeginRequest(object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
HttpContext.Current.Response.End();
}
}
ここでは、OPTIONS動詞をチェックしてチェックに合格するだけです。
Web.configにカスタムヘッダーを追加したところ、魅力的に機能しました。
設定時-system.webServer:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
フロントエンドアプリとバックエンドを同じソリューションで使用しています。これが機能するためには、Webサービスプロジェクト(バックエンド)をデフォルトの機能として設定する必要があります。
私はReSTを使用していましたが、他に試したことはありません。
Web.config CORSにいくつかの変更を加えた後、Web API 2プロジェクトでCORSが突然機能しなくなりました(少なくともプリフライト中のOPTIONSリクエストの場合)。 Web.configに以下のセクションがある必要があるようです。さもないと、(グローバルな)EnableCorsAttributeはOPTIONSリクエストで動作しません。これは、Visual Studioが新しいWeb API 2プロジェクトに追加するセクションとまったく同じであることに注意してください。
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
これらの答えのどれも実際には機能しません。他の人が指摘したように、Corsパッケージは、リクエストにOriginヘッダーがある場合にのみAccess-Control-Allow-Originヘッダーを使用します。しかし、一般的にブラウザはリクエストにOriginヘッダーを追加することはできません。ブラウザーもそれを規制しようとするからです。
Web APIへのクロスサイトリクエストを許可するための迅速で汚れた方法が必要な場合は、カスタムフィルター属性を記述する方がはるかに簡単です。
public class AllowCors : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
if (actionExecutedContext == null)
{
throw new ArgumentNullException("actionExecutedContext");
}
else
{
actionExecutedContext.Response.Headers.Remove("Access-Control-Allow-Origin");
actionExecutedContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
}
base.OnActionExecuted(actionExecutedContext);
}
}
次に、コントローラーアクションで使用します。
[AllowCors]
public IHttpActionResult Get()
{
return Ok("value");
}
一般にこのセキュリティを保証するつもりはありませんが、web.configでヘッダーを設定するよりもおそらく安全です。なぜなら、この方法では、必要なだけ具体的に適用できるからです。
そしてもちろん、特定の起源、メソッドなどのみを許可するように上記を変更するのは簡単です。
WEBAPI2:ソリューション。 global.asax.cs:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
ソリューションエクスプローラーで、api-projectを右クリックします。プロパティウィンドウで'Anonymous Authentication' to Enabled !!!
これが将来誰かを助けることを願っています。
CORSをグローバルに有効にする を試みて、この同じ問題が発生しました。しかし、私はそれがわかったdoesが、リクエストにOrigin
ヘッダー値が含まれている場合にのみ動作します。 Origin
ヘッダー値を省略すると、応答にはAccess-Control-Allow-Origin
が含まれません。
DHC というchromeプラグインを使用して、GETリクエストをテストしました。 Origin
ヘッダーを簡単に追加できました。
Neerajよりも安全で、Matthewよりも簡単であるために、私にとって安全なソリューションはありません。次を追加してください:System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
コントローラーのメソッド内。それは私のために働く。
public IHttpActionResult Get()
{
System.Web.HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
return Ok("value");
}
ほとんどのブラウザが送信するOPTIONSリクエストに問題があるため、この質問を見つけました。私のアプリはOPTIONSリクエストをルーティングし、IoCを使用して多くのオブジェクトを構築し、いくつかはさまざまな理由でこの奇妙なリクエストタイプで例外をスローしていました。
基本的にすべてのOPTIONSリクエストが問題を引き起こしている場合は、無視ルートに入れます:
var constraints = new { httpMethod = new HttpMethodConstraint(HttpMethod.Options) };
config.Routes.IgnoreRoute("OPTIONS", "{*pathInfo}", constraints);
これが将来誰かを助けることを願っています。私の問題は、グローバルなCORSを有効にするためにOPと同じチュートリアルに従っていたことです。ただし、AccountController.csファイルでアクション固有のCORSルールも設定します。
[EnableCors(origins: "", headers: "*", methods: "*")]
また、Originがnullまたは空の文字列であってはならないというエラーが表示されていました。しかし、すべての場所のGlobal.asax.csファイルでエラーが発生していました。解決策は次のように変更することです。
[EnableCors(origins: "*", headers: "*", methods: "*")]
起源に*がありますか? Global.asax.csファイルでエラーが発生した原因はそれでした。
これが誰かを助けることを願っています。