web-dev-qa-db-ja.com

Angular2からREST WebApi CORSの問題

Angular2フロントエンドとWebApiバックエンドを使用しています。 webapiはCORS対応です

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

このAPIを使用するさまざまなサイト(jQuery/Javascript)があるため、機能します。しかし、angular2ではそうではありません。次のメッセージが表示されます。

プリフライトリクエストへの応答がアクセスコントロールチェックに合格しません。リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。

「プリフライトリクエスト」に関連するものでしょうか?

17
Marcos

Angular2アプリケーションでも同じ問題が発生しました。既に述べたように、問題は、クライアントからのすべてのリクエストの前にpreflight requestがサーバーに送信されることです。

この種の要求には、タイプ[〜#〜] options [〜#〜]があり、ステータス200とヘッダーでプリフライト応答を送り返すことがサーバーの義務です。そのクライアントからのリクエストを受け入れるために設定されます。

これは私のソリューションです(エクスプレス):

// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');

// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');

// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');

// Set to true if you need the website to include cookies in  requests
res.setHeader('Access-Control-Allow-Credentials', true);

// Check if preflight request
if (req.method === 'OPTIONS') {
    res.status(200);
    res.end();
}
else {
    // Pass to next layer of middleware
    next();
}

ご覧のとおり、ヘッダーを設定してから、リクエストタイプが[〜#〜] options [〜#〜]の場合にフェッチします。その場合、ステータス200を送り返し、応答を終了します。

このようにして、クライアントは承認され、すべてのリクエストでカスタムヘッダーを設定することもできます。

9
Matteo Tosi

エラーメッセージは、呼び出しの応答にAccess-Control-Allow-Originがないことを示しています。このリクエストに対してCORSを有効にする必要があります。これはAngular2に関連するものではありません。

これは、リクエストにOriginヘッダーを追加することにより、クライアント側でトリガーされます。リクエストにこのヘッダーがありますか?他のアプリケーションでプリフライトリクエストを使用していますか。念のため:

  • 単純なリクエスト。この使用例は、HTTP GETを使用する場合に適用されます。HEADおよびPOSTメソッド。POSTメソッドの場合、次の値を持つコンテンツタイプがサポートされています:text/plainapplication/x-www-form-urlencoded、およびmultipart/form-data
  • プリフライトされたリクエスト。 「単純なリクエスト」のユースケースが適用されない場合、クロスドメインリクエストのコンテキストで何ができるかを確認するために、最初のリクエスト(HTTP OPTIONSメソッドを使用)が行われます。

おそらく、OPTIONS要求はサーバー側で正しく処理されません(正しいヘッダーを返さないなど)。

興味があるのは、どのリクエストでエラーが発生したかを伝えることです:OPTIONS oneまたはtarget request。 DevToolsのNetworkタブをご覧ください...

CORSの機能の詳細については、次のリンクを参照してください。

お役に立てばと思います、ティエリー

8

Corsのweb.configファイルにオプションが設定されていますか?つまり、<add name="Access-Control-Allow-Origin" value="*"/>

はいの場合は、それを必ず削除し、コードのみでCORを制御します。

回答 here が役立ちます。

1
Chidilives

開発目的で this Chrome拡張機能を追加し、クロスオリジンリソース共有を有効にします。

1
Shamsul

私は質問がPHPコードを求めているのではないことを知っています。このプリフライトとAngular2のおかげでここに来ました。これは、プリフライトブラウザで認証トークンを送信しないため、サーバーが401で戻ってきて、ブラウザがCORSが許可されていないと判断するためです。以下のコードは、開発サーバーでのみ使用してください。あなたはやっている。

PHPでこれを行うことができます:

if (strtolower($_SERVER['REQUEST_METHOD']) === 'options') {
         header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_Origin']);
         header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
         header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Range, Content-Disposition, Content-Type, Authorization');
         header('Access-Control-Allow-Credentials: true');
         echo 'Allowed';
         exit;
}

またはNginx

if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        #
        # Custom headers and headers various browsers *should* be OK with but aren't
        #
        add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
        #
        # Tell client that this pre-flight info is valid for 20 days
        #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }

サーバーに送信する他のヘッダーはすべて、Access-Control-Allow-Headersリストに追加する必要があることに注意してください。

1
Jsonras

また、corsとangular 6。

サーバーへの要求が基本的な要求ではない場合、サーバーが要求に応答できるかどうかを尋ねるプリフライト要求があります。

サーバーはそのリクエストに応答し、それらのヘッダーを持つ必要があります:

Access-Control-Allow-Origin //ドメインにする必要があります

Access-Control-Allow-Headers // Accept、Origin、その他のヘッダーがある必要があります。

Access-Control-Allow-Method //使用するすべてのメソッド

これらは、すべてを受け入れるためにCors属性として追加した「*」、「*」、「*」ですが、クライアントとサーバーの両方が同じマシン上にある場合、開発モードでのみ機能しました。 IISサーバーで本番環境に移動した後、特にヘッダーのためにこれらの値は機能しませんでした。

修正するのは本当に簡単で、IOS代わりに動作します* * *各コントローラーにこれを追加しました:

[EnableCors(origins: "enter your domain here", headers: "authorization, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers", methods: "GET,POST", PreflightMaxAge = 600 // optional, SupportsCredentials = true // optional)]

あなたは私が何をする必要があるかを理解するのを助けた記事でもっと読むことができます: https://msdn.Microsoft.com/en-us/magazine/dn532203.aspx

Tomerさん、お役に立てば幸いです。

0
Tomer Halaf

Firefoxブラウザーに1つのアドオンを追加できます。これは、Firefoxブラウザーでチャームのように機能します。 Cors Everywhereは私の問題を解決しました。 https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/

0
SUBHASIS MONDAL

私はAngular 2をフロントエンドで、nodeJS(Expressjs)でAPIを使用しています)

Angular 2はlocalhost:3000で動作しており、expressはlocalhost:8000で動作しています

Localhost:3000がPOST method ...を使用してURLを呼び出そうとすると、問題が発生します...

この問題を解決するには、localhost:3000サーバーからの呼び出しを受け入れるようにノードjsに指示する必要があります...

このリンクでこの問題を回避するライブラリ(CORS)を見つけることができます