web-dev-qa-db-ja.com

Web API 2でCORSを有効にする

クライアントとサーバーが異なるポートで実行されています。サーバーは実行中ですWeb API 2(v5.0.0-rc1)

Microsoft ASP.NET Web APIクロスオリジンサポートパッケージ をインストールしてみて、WebApiConfig.csで有効にしました。 EnableCors()関数が提供されるため、パッケージは正しくインストールされました。

ここで、WebApiConfig.csで私のRegister()関数を見ることができます:

public static void Register(HttpConfiguration config)
{
    config.MapHttpAttributeRoutes();

    var cors = new EnableCorsAttribute("*", "*", "*");
    config.EnableCors(cors);
}

GETリクエストは正常に機能します。しかし、POSTを送信すると、次のメッセージが表示されます。

OPTIONS http://localhost:19357/api/v1/rooms? 404 (Not Found) angular.js:10159
OPTIONS http://localhost:19357/api/v1/rooms? Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin. angular.js:10159
XMLHttpRequest cannot load http://localhost:19357/api/v1/rooms. Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin.

Fiddlerによると、OPTIONSリクエストのみを送信します。その後POSTを発行しません。

WebApiConfig.csconfig.EnableCors(cors);は何もしていないと推測しているため、サーバーがPOSTリクエストの送信をクライアント/ブラウザに拒否します。

この問題を解決する方法はありますか?

EDIT 05.09.13これは5.0.0-rtm-130905で修正されました

54
Gaui

私は間違いなく この問題 属性ルーティングでヒットしています。 問題修正済み 5.0.0-rtm-130905の時点でした。しかし、それでも nightly builds を試すことができますが、これは間違いなく修正されます。

NuGetパッケージソースにナイトリーを追加するには、Tools -> Library Package Manager -> Package Manager Settingsに移動し、Package Sourcesの下に次のURLを追加します。 http://myget.org/F/aspnetwebstacknightly

6
Gaui

CORSはMicrosoft.AspNet.WebApi.Corsバージョン5.2.2で完全に機能します。次の手順は、CORSを私にとって魅力のように構成しました。

  1. Install-Package Microsoft.AspNet.WebApi.Cors -Version "5.2.2" //パッケージマネージャーコンソールから実行
  2. Global.asaxで、次の行を追加します。任意のMVCルート登録前

    GlobalConfiguration.Configure(WebApiConfig.Register);
    
  3. WebApiConfig Registerメソッドに、次のコードがあります。

    public static void Register(HttpConfiguration config)
    {
        config.EnableCors();
        config.MapHttpAttributeRoutes();
    }
    

Web.configでは、次のハンドラーがパイプラインの最初のハンドラーである必要があります。

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

ApiControllerから派生したコントローラーで、EnableCorsAttributeを追加します。

[EnableCors(origins: "*", headers: "*", methods: "*")] // tune to your needs
[RoutePrefix("")]
public class MyController : ApiController

これでうまくセットアップできます!

55

パッケージをインストールする必要はありませんでした。 WebAPIプロジェクトのweb.configを少し変更するだけでうまく機能します。

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

クレジット: ロケット科学者にならずにASP.NET WebAPIでCORSを使用

34

HTTPS経由でWebAPIにアクセスしていることを確認してください。

また、WebApi.configでcorsを有効にしました。

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

しかし、HTTPS URLを使用するまで、CORS要求は機能しませんでした。

5
tno2007

将来の参照のための遅い返信。私のために働いていたのは、nugetによってそれを有効にしてから、web.configにカスタムヘッダーを追加することでした。

4
Mariusz

DelegatingHandlerを使用してメッセージパイプラインをインターセプトした場合、[EnableCors()]アプローチを使用した参照は機能しません。私の場合、リクエストのAuthorizationヘッダーをチェックし、ルーティングが呼び出される前にそれに応じて処理していました。つまり、リクエストはパイプラインの早い段階で処理されるため、[EnableCors()]は効果がありません。

最後に例が見つかりました CrossDomainHandler classshaunx for GistパイプラインでCORSを処理し、それを使用するのは、パイプラインに別のメッセージハンドラーを追加するのと同じくらい簡単です。

public class CrossDomainHandler : DelegatingHandler
    {
        const string Origin = "Origin";
        const string AccessControlRequestMethod = "Access-Control-Request-Method";
        const string AccessControlRequestHeaders = "Access-Control-Request-Headers";
        const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
        const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
        const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";

        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            bool isCorsRequest = request.Headers.Contains(Origin);
            bool isPreflightRequest = request.Method == HttpMethod.Options;
            if (isCorsRequest)
            {
                if (isPreflightRequest)
                {
                    return Task.Factory.StartNew(() =>
                    {
                        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
                        response.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());

                        string accessControlRequestMethod = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault();
                        if (accessControlRequestMethod != null)
                        {
                            response.Headers.Add(AccessControlAllowMethods, accessControlRequestMethod);
                        }

                        string requestedHeaders = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders));
                        if (!string.IsNullOrEmpty(requestedHeaders))
                        {
                            response.Headers.Add(AccessControlAllowHeaders, requestedHeaders);
                        }

                        return response;
                    }, cancellationToken);
                }
                else
                {
                    return base.SendAsync(request, cancellationToken).ContinueWith(t =>
                    {
                        HttpResponseMessage resp = t.Result;
                        resp.Headers.Add(AccessControlAllowOrigin, request.Headers.GetValues(Origin).First());
                        return resp;
                    });
                }
            }
            else
            {
                return base.SendAsync(request, cancellationToken);
            }
        }
    }

使用するには、登録済みメッセージハンドラーのリストに追加します

config.MessageHandlers.Add(new CrossDomainHandler());

ブラウザによるプリフライトリクエストはすべて処理されて渡されます。つまり、コントローラに[HttpOptions]IHttpActionResultメソッドを実装する必要はありませんでした。

4
Lankymart
 var cors = new EnableCorsAttribute("*","*","*");
 config.EnableCors(cors);

 var constraints = new {httpMethod = new HttpMethodConstraint(HttpMethod.Options)};
 config.Routes.IgnoreRoute("OPTIONS", "*pathInfo",constraints);
3
Vikas