JavaScriptコードでPostmanが「要求されたリソースに「Access-Control-Allow-Origin」ヘッダーが存在しない」というエラーが表示されないのはなぜですか?


2503

Modの注記:この質問は、なぜPostmanがXMLHttpRequestと同じようにCORS制限を受けない理由についてです。この質問はありません「いいえ『アクセス制御-許可-起源』 ...」エラーを修正する方法について。

投稿を停止してください


RESTful API組み込みFlaskに接続することにより、JavaScriptを使用して認証を実行しようとしています。しかし、リクエストを行うと、次のエラーが発生します。

XMLHttpRequestがhttp:// myApiUrl / loginを読み込めません。リクエストされたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン「null」はアクセスを許可されません。

APIまたはリモートリソースでヘッダーを設定する必要があることはわかっていますが、Chrome拡張機能Postmanを介してリクエストを送信したときに、なぜそれが機能したのですか?

これはリクエストコードです:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });

32
localhostからリクエストを行っているか、HTMLを直接実行していますか?
MD。サヒブビンマーブーブ2013年

@ MD.SahibBinMahboobあなたの質問を理解したら、localhostからリクエストします-私のコンピューターにページがあり、それを実行します。ホスティングにサイトをデプロイすると、同じ結果が得られます。
ジェダイ氏2013年


8
より多くの読書を探している人のために、MDNはすべてのAJAXとのクロスオリジン・リクエストについての良い記事があります。developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
サム・イートン

1
ノードjsのこのタイプのエラーに関する1つの重要な注意事項。ルートの設定を始める前に、server.jsファイルの起動時にアクセスヘッダーを設定する必要があります。それ以外の場合は、すべてが適切に実行されますが、アプリからリクエストを行うと、このエラーが発生します。
Alex J

回答:


1346

私が正しく理解していれば、ページが表示されているドメインとは異なるドメインに対してXMLHttpRequestを実行しています。したがって、セキュリティ上の理由から、通常は同じオリジンでのリクエストを許可するため、ブラウザはそれをブロックしています。クロスドメインリクエストを行う場合は、別のことを行う必要があります。それを達成する方法についてのチュートリアルはCORSの使用です。

postmanを使用している場合、このポリシーによる制限はありません。Cross-Origin XMLHttpRequestから引用:

通常のWebページでは、XMLHttpRequestオブジェクトを使用してリモートサーバーとの間でデータを送受信できますが、同じ発信元ポリシーによって制限されます。拡張機能はそれほど制限されていません。拡張機能は、最初にクロスオリジンアクセス許可を要求する限り、その外部のリモートサーバーと通信できます。


7
あなたが正しい。私のページとは異なるドメインへのリクエストを行っています。APIはサーバー上にあり、ローカルホストからリクエストを実行します。回答を受け入れる前に、「リクエストを直接実行する」とはどういう意味ですか?ポストマンはドメインを使用しませんか?
ジェダイ氏2013年

181
ブラウザはリクエストをブロックしていません。クロスオリジンのAjaxリクエストを完全にブロックするブラウザは、IE7以前のみです。IE7以前を除くすべてのブラウザーは、CORS仕様を実装しています(IE8およびIE9を部分的に)。必要なのは、リクエストに基づいて適切なヘッダーを返すことにより、APIサーバーでCORSリクエストをオプトインすることだけです。mzl.la/VOFrSzでCORSの概念を確認する必要があります。PostmanもXHR経由でリクエストを送信します。postmanを使用しても同じ問題が発生しない場合は、知らないうちに同じ要求をpostman経由で送信していないことを意味します。
レイニコラス2013年

10
@ MD.SahibBinMahboob Postmanは、「java / pythonからの」コードからリクエストを送信していません。ブラウザから直接リクエストを送信しています。 Chrome拡張機能のXHRは、特にクロスオリジンリクエストが関係する場合、動作が少し異なります
レイニコラス2013年

250

警告:を使用Access-Control-Allow-Origin: *すると、API /ウェブサイトがクロスサイトリクエストフォージェリ(CSRF)攻撃に対して脆弱になる可能性があります。このコードを使用する前に、リスクを確実に理解してください。

PHPを使用している場合は、非常に簡単に解決できます。リクエストを処理する次のスクリプトをPHPページの先頭に追加するだけです。

<?php header('Access-Control-Allow-Origin: *'); ?>

Node-redを使用している場合は、次の行のコメントを外して、node-red/settings.jsファイルでCORSを許可する必要があります。

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 origin: "*",
 methods: "GET,PUT,POST,DELETE"
},

質問と同じFlaskを使用している場合; 最初にインストールする必要がありますflask-cors

$ pip install -U flask-cors

次に、Flask corsをアプリケーションに含めます。

from flask_cors import CORS

単純なアプリケーションは次のようになります。

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

詳細については、Flaskのドキュメントを確認してください。


93
安全ではありません
llazzaro 2014

153
CORSの目的がわからないため、CORS をオフにしないでください。これはひどい答えです。
貧弱

124
安全ではないかもしれませんが、問題はセキュリティについてではなく、タスクをどのように達成するかでした。これは、クロスドメインAJAXリクエストを処理するときに開発者が選択する必要があるオプションの1つです。それは私が問題を解決するのに役立ちました、そして私のアプリケーションのために、私はデータがどこから来たのか気にしません。私は宛先ドメインでPHPを使用してすべての入力をサニタイズします。そのため、誰かがジャンクを投稿したい場合は、試してみてください。ここでの要点は、クロスドメインAJAXが宛先ドメインから許可されることです。答えは+1。
ZurabWeb 2015

23
私はピエロが与える一般的なメッセージに同意しますが、それは特にセキュリティに関するものではありませんが、セキュリティは懸念事項です。これは少なくとも、「これは一般的に悪いことです。何をしているのか分からない限り、これを行わないでください!これに関するドキュメントは次のとおりです...」と、おそらく簡単に理由を説明しているはずです。私は誰かがここに来るのが嫌で、「ああ、私はこのヘッダーを追加/調整するだけでいいのです!」と思います。完全な影響を知りません。つまり、それは彼らにとって、研究することとすべてのものですが、それでもまだです。
トーマスF.

4
私はこの答えが好きです...私は同じ問題を抱えており、それを解決します...彼はいくつかのセキュリティ問題があると説明しましたが、それは別の問題であり、誰もが個別にその問題を考えて解決できるようにします...
Ari Waisberg

64

そのため
$アヤックス({タイプ: "POST" -通話のOPTIONS
$ .postが( -呼び出しPOSTを

どちらも違います。Postmanは "POST"を適切に呼び出しますが、これを呼び出すと、 "OPTIONS"になります。

C#Webサービスの場合-Web API

<system.webServer>タグの下のweb.configファイルに次のコードを追加してください。これは動作します:

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

Ajax呼び出しで間違いがないことを確認してください

jQuery

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);
    },
    error: function () {
        console.log("error");
    }
});

注:サードパーティのウェブサイトからコンテンツをダウンロードすることを探している場合、これは役に立ちません。次のコードを試すことはできますが、JavaScriptは試すことができません。

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");

この構成は、Azure ServicesのWordpressでの同じエラーを解決しました。ありがとう。
アンドレメスキータ

9
外部ドメインからのリクエストを回避するために、特定のオリジン値を使用することをお勧めします。たとえば、*使用する代わりにhttps://www.myotherdomain.com
pechar 2017年


8

CORS制限の適用は、サーバーによって定義され、ブラウザによって実装されるセキュリティ機能です

ブラウザはサーバーのCORSポリシーを確認し、それを尊重します。

ただし、PostmanツールはサーバーのCORSポリシーを気にしません。

そのため、ブラウザにはCORSエラーが表示されますが、Postmanには表示されません。


1
はい、なぜこの細部に注意が必要なのかを十分に強調することはできません。セキュリティについて話すとき、CORSはそれを実装しているクライアントと同じくらい強力であることを述べることが最も重要です。したがって、単純なHttpClient(サーバー側コード)を使用してプロキシを構築し、プロキシが要求を実行するとします。セキュリティは完全に回避され、CORS標準は貧弱なソリューションとして残されます
Christopher Bonitz

7

以下のAPIとしての調査では、質問のhttp:// myApiUrl / loginの代わりにhttp://example.comを使用しています。

あなたのページはhttp://my-site.local:8088にあると思います

異なる結果が表示される理由は、Postmanが次のようになっているためです。

  • ヘッダーを設定するHost=example.com(API)
  • ヘッダーを設定しない Origin

これは、サイトとAPIが同じドメインの場合にブラウザーがリクエストを送信する方法に似ています(ブラウザーもヘッダー項目を設定しますがReferer=http://my-site.local:8088、Postmanには表示されません)。ヘッダーが設定されていない場合、通常、サーバーはデフォルトでそのような要求を許可します。Origin

ここに画像の説明を入力してください

これは、Postmanがリクエストを送信する標準的な方法です。ただし、サイトとAPIのドメインが異なる場合、ブラウザはリクエストを異なる方法で送信し、次にCORSが発生してブラウザが自動的に実行されます。

  • ヘッダーを設定しますHost=example.com(自分のAPIとして)
  • ヘッダーを設定しOrigin=http://my-site.local:8088ます(サイト)

(ヘッダーのReferer値はと同じですOrigin)。Chromeの[ コンソールとネットワーク ]タブに次のように表示されます。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

あなたが持っている場合はHost != Origin、これをCORSであり、サーバがそのような要求を検出し、それは通常、デフォルトでブロックして

Origin=nullローカルディレクトリからHTMLコンテンツを開いたときに設定され、リクエストを送信します。<iframe>以下のスニペットのように内でリクエストを送信する場合も同じ状況です(ただし、ここではHostヘッダーはまったく設定されていません)。一般に、HTML仕様で不透明な原点が示されている場所であればどこでも、に変換できますOrigin=null。この詳細については、こちらをご覧ください

fetch('http://example.com/api', {method: 'POST'});
Look on chrome-console > network tab

単純なCORSリクエストを使用しない場合、通常、ブラウザはメインリクエストを送信する前にOPTIONSリクエストも自動的に送信します。詳細はこちらです。以下のスニペットはそれを示しています:

fetch('http://example.com/api', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json'}
});
Look in chrome-console -> network tab to 'api' request.
This is the OPTIONS request (the server does not allow sending a POST request)

CORSリクエストを許可するようにサーバーの設定を変更できます。

これは、nginx(nginx.confファイル)でCORSをオンにする設定例です。nginx always/"$http_origin""*"Apacheの設定には十分注意してください。これにより、どのドメインからでもCORSのブロックが解除されます。

Apache(.htaccessファイル)でCORSを有効にする設定例を以下に示します。


2

異なるユースケースで同じエラーが発生しました。

使用例: Spring RESTエンドポイントを角度で呼び出そうとしたときのクロム。

ここに画像の説明を入力してください

解決策:それぞれのコントローラークラスの上に@CrossOrigin( "*")アノテーションを追加します。

ここに画像の説明を入力してください


セキュリティのために*ではなくlocalhostを使用します
neo7bf

-1

中間層として.NETを使用している場合は、たとえばroute属性を明確に確認してください。

こんな時に問題ありましたが、

[Route("something/{somethingLong: long}")] //Space.

これで修正、

[Route("something/{somethingLong:long}")] //No space

-1

.NET Core Web APIプロジェクトの場合のみ、次の変更を追加します。

  1. Startup.csファイルのメソッドのservices.AddMvc()行の後に次のコードを追加しConfigureServices()ます。
services.AddCors(allowsites=>{allowsites.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin());
            });
  1. Startup.csファイルのメソッドのapp.UseMvc()行の後に次のコードを追加しConfigure()ます。
app.UseCors(options => options.AllowAnyOrigin());
  1. ドメイン外にアクセスするコントローラーを開き、コントローラーレベルで次の属性を追加します。
[EnableCors("AllowOrigin")]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.