プリフライト要求への応答がアクセス制御チェックに合格しません


457

ngResourceを使用してアマゾンウェブサービスでREST APIを呼び出すと、このエラーが発生します。

XMLHttpRequestがhttp://server.apiurl.com:8000/s/login?login=facebookを読み込めません 。プリフライト要求への応答がアクセス制御チェックに合格しません:要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン ' http:// localhost 'はアクセスを許可されません。 エラー405

サービス:

socialMarkt.factory('loginService', ['$resource', function($resource){    
    var apiAddress = "http://server.apiurl.com:8000/s/login/";
    return $resource(apiAddress, { login:"facebook", access_token: "@access_token" ,facebook_id: "@facebook_id" }, {
                getUser: {method:'POST'}
            });
}]);

コントローラ:

[...]
loginService.getUser(JSON.stringify(fbObj)),
                function(data){
                    console.log(data);
                },
                function(result) {
                    console.error('Error', result.status);
                }
[...]

私はChromeを使用していますが、この問題を解決するために他に何をすべきかわかりません。originからのヘッダーを受け入れるようにサーバーを構成しましたlocalhost


混乱:「サーバーを設定」しましたか、それとも「Amazon WebサービスのREST API」ですか?
dandavis 2016

3
サーバーサイドでCORSを有効にするのに十分なことをしていないことは明らかです。応答ヘッダーのサンプルの投稿
charlietfl

4
どちらにしても、反対票は間違っています。彼は自分のローカルマシンでファイルをホストしています。彼がバックエンドでどのような設定を行うかは問題ではありません。Angularは、このプレフライトを許可しません。
E.マグジーニ

3
コメントのThx、それは私がセキュリティをオフにするようにブラウザを設定したときにうまくいきました
Andre Mendes

1
@Andreしかし、セキュリティをオフにすることは、セキュリティを危険にさらしている醜い回避策であり、問​​題を解決しない...
shivi

回答:


240

CORSの問題が発生しています。

これを修正/回避するにはいくつかの方法があります。

  1. CORSをオフにします。例えば: ChromeでCORをオフにする方法
  2. ブラウザーのプラグインを使用する
  3. nginxなどのプロキシを使用します。 セットアップ方法の例
  4. サーバーに必要な設定を行います。これは、EC2インスタンスにロードしたWebサーバーのより多くの要因です(これが「Amazon Webサービス」の意味するところと想定しています)。特定のサーバーについては、CORS Webサイトを参照してください

より詳細には、localhostからapi.serverurl.comにアクセスしようとしています。これは、クロスドメインリクエストの正確な定義です。

あなたの仕事を終わらせるためだけにそれをオフにすることで(OK、他のサイトにアクセスし、すぐに缶を蹴るだけならセキュリティを貧弱にしてください)、プロキシを使用してブラウザがすべてのリクエストがローカルホストからのものであると考えさせることができます実際には、リモートサーバーを呼び出すローカルサーバーがあります。

そのため、api.serverurl.comがlocalhost:8000 / apiになり、ローカルのnginxまたは他のプロキシが正しい宛先に送信されます。


今や人気の需要により、CORS情報が100%増えました


そして、ダウンボッターにとって... CORSをバイパスすることは、フロントエンドを単に学ぶ人たちのために示されているものと全く同じです。 https://codecraft.tv/courses/angular/http/http-with-promises/


776
CORSを正しく実装するという明らかなものは
省略し

40
反対票を投じるのは簡単です。自分のリスクを自分の友人が取るのは簡単ではありません。そして、これらはすべて、開発環境で正確に機能します。
E.マグジーニ2016

3
それは実際に働きました。Webセキュリティを無効にするフラグを追加しました。開発には問題ありません。
Andre Mendes

15
@charlietflどうやって?
GreenAsJade

3
私の日を救ってくれてありがとう 最初のオプションのみを使用:C:\ Program Files(x86)\ Google \ Chrome \ Application> chrome.exe --user-data-dir = "C:\ Chrome dev session" --disable-web-security。From:stackoverflow.com/questions/3102819/...
Harsimer

169

私の「APIサーバー」はPHPアプリケーションなので、この問題を解決するために、以下の解決策が機能することがわかりました。

index.phpに行を配置します

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS');
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');

3
これらの行をコピーするときは注意が必要ですが、メソッドとオリジンを変更してください。
Amir Savand

11
Angular 6プロジェクトのどこに置くべきですか?
whatthefish '07 / 07/18

@CodyBugsteinとwhatthefishが出力の前に置く
Garet Claborn

一部のサーバーでのみ必要なヘッダーを追加すると、クライアントアプリが動作を停止しました。リクエストにカスタムヘッダーが含まれている場合は、それらをにリストする必要がありますAccess-Control-Allow-Headers
z0r

47

AspNetCore Web APIでは、この問題は「Microsoft.AspNetCore.Cors」(ver 1.1.1)を追加し、Startup.csに以下の変更を追加することで修正されました。

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddCors(options =>
    {
          options.AddPolicy("AllowAllHeaders",
                builder =>
            {
                    builder.AllowAnyOrigin()
                           .AllowAnyHeader()
                           .AllowAnyMethod();
                });
    });
    .
    .
    .
}

そして

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{


    // Shows UseCors with named policy.
    app.UseCors("AllowAllHeaders");
    .
    .
    .
}

[EnableCors("AllowAllHeaders")]コントローラを装着します。


18
これは、クロスサイトスクリプティングの脆弱性を組み込みたい場合の良い答えです。これを行わないでください!セキュリティ上の問題を回避するためにアクセスできるドメインを指定します。CORSは理由があります。
paqogomez 2017年

2
@paqogomezをより明確にするために、ConfigureServicesメソッドで、services.AddCors(options => {options.AddPolicy( "AllowSpecificOrigin"、builder => {builder.WithOrigins( " localhost").AllowAnyOrigin().AllowAnyHeader())を使用します。 AllowAnyMethod();});}); そしてあなたのConfigureメソッドで:app.UseCors( "AllowSpecificOrigin");
Francisco Tena 2018年

28

CORSに関しては、いくつかの注意点があります。まず、ワイルドカードは許可されていませ*んが、これを保持していません。どこかで読んだことがあり、現在、記事を見つけることができません。

別のドメインからリクエストを行う場合は、許可元ヘッダーを追加する必要があります。

 Access-Control-Allow-Origin: www.other.com 

POST / PUT / PATCHなどのサーバーリソースに影響を与えるリクエストを作成している場合、およびMIMEタイプが以下と異なる場合 application/x-www-form-urlencodedmultipart/form-dataまたはtext/plainブラウザが自動的に飛行前のオプションは、それを可能にする場合は、サーバーに確認するように要求ようになります。

API /サーバーはこれらのOPTIONSリクエストを適切に処理する必要があるため、適切な access control headersあり、http応答ステータスコードはである必要があります200

ヘッダーは次のようになります。必要に応じて調整してください。

   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

max-ageヘッダーは重要です。私の場合、それがないと機能しません。ブラウザには、「アクセス権」が有効な期間の情報が必要だと思います。

さらに、たとえば別のドメインからのMIMEを使用したPOSTリクエストを行う場合は、application/json前述の許可元ヘッダーを追加する必要があるため、次のようになります。

   Access-Control-Allow-Origin: www.other.com 
   Access-Control-Allow-Methods: GET, POST, PUT, PATCH, POST, DELETE, OPTIONS
   Access-Control-Allow-Headers: Content-Type
   Access-Control-Max-Age: 86400

プリフライトが成功し、必要なすべての情報を取得すると、実際のリクエストが行われます。

一般的に言って、 Access-Control最初の要求または飛行前の要求で要求されるヘッダーは、それが機能するために応答で指定する必要があります。

このリンクの MDNドキュメントの良い例があり、このSOの投稿も確認する必要があります


1
ここでは、CORS原点にワイルドカードを使用することはできませんどのように話してMozillaの記事です: リンク の資格情報を使用している場合(私が正しく理解していた場合)ので、明らかにこれはのみ適用されます
Helzgate

ワイルドカードを使用してリクエストを承認するために無記名トークンを送信していますが、問題なく機能しているため、上記で提供したリンクが資格情報に関してどのリンクを参照しているかはわかりません。私の問題は、.NET CoreでCORSポリシーを作成するときに追加しなかったこと.AllowCredentials()です。.AllowCredentials()すべてを追加した後、機能しました。
Helzgate

15

JavaScript XMLHttpRequestFetchは、同一生成元ポリシーに従います。そのため、XMLHttpRequestまたはFetchを使用するWebアプリケーションは、自身のドメインに対してのみHTTPリクエストを行うことができました。

ソース:https : //developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

サーバー側からAccess-Control-Allow-Origin:* HTTPヘッダーを送信する必要があります。

ApacheをHTTPサーバーとして使用している場合は、次のようにそれをApache構成ファイルに追加できます。

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
</IfModule>

ApacheではデフォルトでMod_headersが有効になっていますが、次のコマンドを実行して有効にすることができます。

 a2enmod headers

Apache構成ファイルはどこにありますか?
Shubham Arya、2018

@ShubhamAryaは、LinuxのDebianのデフォルトの場所は次のとおりです。/etc/apache2/apache2.conf
タデイ

窓のどこにありますか?
Shubham Arya

10

クロム拡張機能を作成している場合

manifest.jsonドメインの権限を追加する必要があります。

"permissions": [
   "http://example.com/*",
   "https://example.com/*"
]

1
また、wwwプレフィックスがあるかどうかも確認してください
Vlas Bashynskyi

8

偶然にIISサーバーを使用している場合。HTTPリクエストヘッダーオプションでヘッダーの下に設定できます。

Access-Control-Allow-Origin:*
Access-Control-Allow-Methods: 'HEAD, GET, POST, PUT, PATCH, DELETE'
Access-Control-Allow-Headers: 'Origin, Content-Type, X-Auth-Token';

これですべての投稿、取得などが正常に動作します。



5

PHPでは、ヘッダーを追加できます。

<?php
header ("Access-Control-Allow-Origin: *");
header ("Access-Control-Expose-Headers: Content-Length, X-JSON");
header ("Access-Control-Allow-Methods: GET, POST, PATCH, PUT, DELETE, OPTIONS");
header ("Access-Control-Allow-Headers: *");
...

おかげで、うまくいきました!テストおよび実稼働環境で。https://を使用していても
Jose Seie

1
@atiruz解決策をありがとう。これは私がラインを追加したときに機能しますheader ("Access-Control-Expose-Headers: Content-Length, X-JSON");
Silambarasan RD

5

Node JSアプリケーションでクロスオリジンリクエストの問題を修正するには:

npm i cors

そして、以下の行を app.js

let cors = require('cors')
app.use(cors())

3
これはすべてのノードアプリではなく、エクスプレスjsアプリでのみ機能します
DrCord

3

私のApache VirtualHost構成ファイルに、次の行を追加しました。

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Max-Age "1000"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"

RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]

3

それらのAPIゲートウェイでLambda統合プロキシを使用しています。ラムダ関数をリクエストを直接送信するかのように構成する必要があります。つまり、関数は応答ヘッダーを適切に設定する必要があります。(カスタムラムダ関数を使用している場合、これはAPI Gatewayによって処理されます。)

//In your lambda's index.handler():
exports.handler = (event, context, callback) => {
     //on success:
     callback(null, {
           statusCode: 200,
           headers: {
                "Access-Control-Allow-Origin" : "*"
           }
     }
}

1
AWSのドキュメントとは思えない大きな落とし穴についても触れたいと思います。APIゲートウェイを使用してラムダ関数をプロキシし、そのラムダ関数でいくつかのAPIを使用するとします。そのAPIが200以外の成功の成功コードを返し、200以外の成功コードをAPIゲートウェイのメソッド応答に追加しなかった場合、エラーが発生し、成功した応答が表示されません。この例:SendgridとTwilioには200以外の成功コードがあります。
Stephen Tetreault 2018

3

ChromeからCORSを無効にすることは良い方法はないと思います。これをイオンで使用している場合は、確かにMobile Buildで問題が再び発生するためです。

あなたのバックエンドで修正するので良いです。

まず最初に、Inヘッダーを設定する必要があります。

  • header( 'Access-Control-Allow-Origin:*');
  • header( 'Header set Access-Control-Allow-Headers: "Origin、X-Requested-With、Content-Type、Accept"');

APIがGETとPOSTの両方として動作している場合は、ヘッダーにも設定します-

if($ _SERVER ['REQUEST_METHOD'] == 'OPTIONS'){if(isset($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))header( "Access-Control-Allow-Methods:GET、POST、OPTIONS");
if(isset($ _ SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))header( "Access-Control-Allow-Headers:
{$ _SERVER ['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); exit(0); }


3

このエラーの非常に一般的な原因は、ホストAPIがリクエストをhttpメソッド(PUTなど)にマップし、APIクライアントが別のhttpメソッド(POSTまたはGETなど)を使用してAPIを呼び出していることです。


サーバーにCORSを適切に実装していましたが、PUTメソッドを追加するのを忘れていました
fguillen

3

私たちのチームは、Vue、axios、C#WebApiを使用してこれを時折見ます。ヒットしようとしているエンドポイントにルート属性を追加すると、修正されます。

[Route("ControllerName/Endpoint")]
[HttpOptions, HttpPost]
public IHttpActionResult Endpoint() { }

理由はよくわかりません。笑。誰かが私に知らせたら!
w00ngy

1

DNSサーバーが8.8.8.8(Google)に設定されていると、この問題に直面しました。実際、問題はルーターにありました。私のアプリケーションは、ローカルではなく、Googleを介してサーバーに接続しようとしました(私の特定の場合)。8.8.8.8を削除しました。これで問題は解決しました。この問題はCORS設定によって解決されることはわかっていますが、誰かが私と同じ問題を抱えているかもしれません


1

アップロードにAWS SDKを使用していますが、オンラインでの検索にしばらく時間を費やした後、このスレッドに遭遇しました。@lsimoneau 45581857のおかげで、まったく同じことが起こっていました。リージョンオプションをアタッチすることで、リクエストURLをバケットのリージョンにポイントするだけで機能しました。

 const s3 = new AWS.S3({
 accessKeyId: config.awsAccessKeyID,
 secretAccessKey: config.awsSecretAccessKey,
 region: 'eu-west-2'  // add region here });

0

GeoServerのスタンドアロンディストリビューションには、Jettyアプリケーションサーバーが含まれています。クロスオリジンリソースシェアリング(CORS)を有効にして、ドメイン外のJavaScriptアプリケーションがGeoServerを使用できるようにします。

コメントを解除し、次の<filter><filter-mapping>のwebapps / geoserver / WEB-INF / web.xmlのから:

<web-app>
  <filter>
      <filter-name>cross-origin</filter-name>
      <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
  </filter>
  <filter-mapping>
      <filter-name>cross-origin</filter-name>
      <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

これは応答ヘッダーに不快感を与えなかったため、機能しませんでした
JollyRoger 2018

1
GeoServerを使用していませんが、このクリップは、通話を受信するアプリで使用する必要がある設定を知るのに役立ちました。
Matt Felzani

0

何も心配することなく、簡単な手順でこの問題を簡単に解決できます。親切に、それを解決するための手順に従ってください。

  1. 開く(https://www.npmjs.com/package/cors#enabling-cors-pre-flight
  2. インストールに移動し、コマンドnpm install corsをコピーして、ノードターミナルからインストールします。
  3. スクロールして単純な使用法(すべてのCORSリクエストを有効にする)に移動します。次に、urプロジェクトに完全な宣言をコピーして貼り付けて実行します...これは確実に機能します。コメントコードをコピーして、ur app.jsまたはその他の任意の場所に貼り付けますプロジェクトして試してみてください..これは機能します。これにより、すべてのクロスオリジンリソース共有のロックが解除されます。使用のためにサービスを切り替えることができます。

1
var express = require( 'express')var cors = require( 'cors')var app = express()app.use(cors())app.get( '/ products /:id'、function(req、res、次){res.json({msg: 'これはすべてのオリジンでCORS対応です!'})})app.listen(80、function(){console.log( 'ポート80でリスニングするCORS対応のWebサーバー' )})
Rahul sah

-1

見逃しやすいもの...

ソリューションエクスプローラーで、api-projectを右クリックします。プロパティウィンドウで、[匿名認証]を[有効]に設定します!!!


-8

クロムのセキュリティを無効にします。クロムのショートカットを右クリックして作成します->プロパティ->ターゲット、この「C:\ Program Files(x86)\ Google \ Chrome \ Application \ chrome.exe」を貼り付けます--disable-web-security --user -data-dir = "c:/ chromedev"

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