MVC Web API:リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません


128

私はこの記事に書かれているすべてを試しました: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;

        }      
    }
}

1
また、
cors

2
CORSの問題のほとんどはサーバーの構成が原因であるので、おそらく彼の角度コードに問題はありません
sam

同じ種類の設定を行っていますが、APIに存在しないアクションをリクエストし、WebApiが404を返すと、CORSヘッダーが欠落し、ブラウザーが不満を言うことに気付きました。だから、多分それはそれと同じくらい簡単です。
Robin van der Knaap 2014

回答:


296

Web APICORSを有効にする必要があります。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 APIOptionsが実際にをサポートするように構成されていることを確認するには、要求に応答する必要がありますCORS

これを処理するには、空の応答を返信するだけです。アクション内でこれを行うか、次のようにグローバルに行うことができます。

# Global.asax.cs
protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

この追加チェックは、リクエストAPIsのみを受け入れるように設計されGETPOSTリクエストが悪用されないようにするために追加されました。この動詞が存在しないときにデザインにDELETEリクエストを送信することを想像してみてください。結果は予測不可能であり、結果は危険な場合があります。API


4
あなたの答えは私を助けました。私はコードベースのソリューションでできる限りのことを試しました。私はあなたの答えを読むまでweb.configオプションを試しませんでした。機能したのはそれだけでした。なぜだと思いますか?ODataでWeb API 2を使用しています。とにかくありがとう!:)
フェリペコレア

1
将来の参照のために、これに必要なNuGetパッケージは "Microsoft.AspNet.WebApi.Cors"です。
BrainSlugs83

2
私はあなたのすべての答えに従いましたが、2つの質問があります:Application_BeginRequest()はどこで呼び出されるべきですか?次に、同じメソッドで、.Contains( "Origin")は実際にはコンパイルされません。このメソッドは、String.ContainsまたはLinq.Containsからどこにありますか?
meJustAndrew

2
別のポート#は別のドメインを構成することを覚えておいてください。foo.comは異なるドメインである foo.com:8080より
RyBolt

2
あなたは私の命を救う;)
PawełGroński2017

26

@ 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属性を使用した場合の効果は同じです。


ありがとう!! 参考になりました。
Ankit Sahrawat 16

23

私は、Mihai-Andrei Dinculescuによって示された上記のすべての手順を実行しました
しかし、私の場合、以下の行でWeb.Configのhttp OPTIONSが無効になっているため、さらに1つのステップが必要でした。

<remove name="OPTIONSVerbHandler" />

Web.Configから削除しました(以下のようにコメントしてください)。Corsは魅力のように機能します

<handlers>
  <!-- remove name="OPTIONSVerbHandler" / -->
</handlers>

9

Cors nugetパッケージのインストールが原因である可能性があります。

nugetからcorsをインストールして有効化した後に問題が発生した場合は、web Apiを再インストールしてみてください。

パッケージマネージャーから、 Update-Package Microsoft.AspNet.WebApi -reinstall


これはまさに私にとってそれでした。System.Web.Http.Corsをインストールしてからアンインストールしたところ、WebApiが5.2.2から5.2.3の間の間違った(新しくアップグレードされた)バージョンのままでした
TaeKwonJ​​oe

7

CORSが正しく構成されていることを確認するには、これを試してください。

[EnableCors(origins: "*", headers: "*", methods: "*")]

まだ動作していません?HTTPヘッダーの存在を確認してください。


機能しているかどうかを確認するには、supportCredentialsも削除する方が良いです。特定の条件ではcorsが無効になります
harishr

CORSをサイト全体では有効にしたくないので、特定のエンドポイントだけを選択するのが最善の答えです。config.EnableCors()これにも必要です。
Csaba Toth 2017

4

CORSプロトコルを機能させるには、すべてのエンドポイント(またはこのメソッドのグローバルフィルター)に、これらのヘッダーを返すOPTIONSメソッドが必要です。

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

その理由は、ブラウザが最初にOPTIONSリクエストを送信してサーバーを「テスト」し、承認を確認するためです。


2

corsに関する次のケースをキャッチします。多分それは誰かに役立つでしょう。機能「WebDav Redirector」をサーバーに追加すると、PUTおよびDELETEリクエストは失敗します。

したがって、IISサーバーから「WebDAVModule」を削除する必要があります。

  • 「IISモジュール構成で、WebDAVModuleをループアップします。WebサーバーにWebDAVModuleがある場合は、それを削除します」。

または、構成に追加します。

<system.webServer>
<modules>
  <remove name="WebDAVModule"/>
</modules>
<handlers>
  <remove name="WebDAV" />
  ...
</handlers>


2

私はこれに非常に遅れて来ることを知っています。しかし、検索している人なら誰でも、最終的に私のために働いたものを公開したいと思いました。私はそれが最善の解決策であると主張していません-それがうまくいったことだけです。

WebApiサービスはconfig.EnableCors(corsAttribute)メソッドを使用します。ただし、それでも、飛行前のリクエストは失敗します。@ Mihai-Andrei Dinculescuの答えは私に手掛かりを与えました。まず、オプションのリクエストをフラッシュするために彼のApplication_BeginRequest()コードを追加しました。それでもうまくいきませんでした。問題は、WebAPIが予期されたヘッダーをOPTIONSリクエストにまだ追加していないことです。フラッシュだけではうまくいきませんでしたが、アイデアが浮かびました。OPTIONSリクエストの応答にweb.configを介して追加されるカスタムヘッダーを追加しました。これが私のコードです:

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構成によって処理されます。これに対するより良いアプローチがあれば、私はすべて耳です。私にはチートのように感じられ、ヘッダーが自動的に追加された方がいいと思いますが、これが最終的に機能し、次に進むことができました。


1

@ Mihai-Andrei Dinculescuの答えは私にとってうまくいきました、例えば:

  • <httpProtocol>web.configの<system.webServer>セクションにを追加する
  • OPTIONS記載さApplication_BeginRequest()れている経由でリクエストに対して空の応答を返すglobal.asax

Request.Headers.AllKeys.Contains("Origin")リクエストにoriging小文字が含まれているため、彼のチェックが機能しなかったことを除いて、私のブラウザー(Chrome)はCORSリクエストに対してこのように送信すると思います。

代わりに、彼のチェックの大文字と小文字を区別しないバリアントを使用してこれをもう少し一般的に解決しましたContains if (culture.CompareInfo.IndexOf(string.Join(",", Request.Headers.AllKeys), "Origin", CompareOptions.IgnoreCase) >= 0) {


0

次のように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" />

0

私はこの答えで与えられた方法を含め、ネット上で見つけることができるすべてのものを試しました。ほぼ一日中問題を解決しようと試みた後、私は魅力のように私のために働いた解決策を見つけました。

フォルダー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");
        }
    }`

0

人々はおそらくこれは最初は非常に明白だと思うでしょうが、本当にこれについて考えます。これは、何か間違ったことをした場合によく起こります。

たとえば、hostsファイルにホストエントリを追加しなかったため、この問題が発生しました。本当の問題はDNS解決でした。または、ベースURLが間違っています。

IDトークンが1つのサーバーからのものであるにもかかわらず、別のサーバーで使用しようとすると、このエラーが発生することがあります。

リソースが間違っていると、このエラーが発生することがあります。

CORSミドルウェアをチェーンの中に入れすぎると、これが発生する可能性があります。


0

CORS、WebApiCOnfig.csのような複数の場所、プロバイダのGrantResourceOwnerCredentialsメソッド、コントローラヘッダー属性などを有効にしないでください。以下は、アクセス制御の許可元にもなるリストです。

  1. あなたが使っていたDBとのやり取りにトルーブルを持っているWeb。
  2. AWS Cloud Web APIとDBのVPCが異なる場合。

以下のコードは、アクセス制御許可元を修正するのに十分です。// app.UseCorsが構成のコード行の先頭にあることを確認します。

   public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            //All other configurations
        }
    }

これは私の問題を遅らせました。


0

この問題は、別のドメインまたは別のポートからアクセスしようとすると発生します。

Visual Studioを使用している場合は、[ツール]> [NuGetパッケージマネージャー]> [パッケージマネージャーコンソール]に移動します。そこで、NuGetパッケージMicrosoft.AspNet.WebApi.Corsをインストールする必要があります。

Install-Package Microsoft.AspNet.WebApi.Cors

次に、プロジェクト> App_Start> WebApiConfigでCORSを有効にします。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        
        //Enable CORS. Note that the domain doesn't have / in the end.
        config.EnableCors(new EnableCorsAttribute("https://tiagoperes.eu",headers:"*",methods:"*"));

        ....

    }
}

インストールに成功したら、ソリューションをビルドします。これで十分です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.