Angular.jsアプリケーションからサーバーにHTTPリクエストを送信しようとしていますが、いくつかのCORSエラーを解決する必要があります。
HTTP要求は、次のコードを使用して行われます。
functions.test = function(foo, bar) {
return $http({
method: 'POST',
url: api_endpoint + 'test',
headers: {
'foo': 'value',
'content-type': 'application/json'
},
data: {
bar:'value'
}
});
};
最初の試行では、いくつかのCORSエラーが発生しました。したがって、次の行をPHPスクリプトに追加しました:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding, X-Auth-Token, content-type');
最初のエラーは解消されました。
Chromeのデベロッパーコンソールに次のエラーが表示されます。
angular.js:12011オプション http:// localhost:8000/test (無名関数)
423ef03a:1 XMLHttpRequestが読み込めません http:// localhost:8000/test 。プリフライトの応答に無効なHTTPステータスコード400が含まれています
そして、ネットワークリクエストは私が期待したように見えます(HTTPステータス400
も期待されます):
リクエストがOPTIONS
としてlocalhostに送信され、POST
としてリモートサーバーに送信される理由を解決する方法(および理解方法)を想像できません。この奇妙な問題を解決する方法はありますか?
OPTIONS
リクエストは、いわゆる プリフライトリクエスト と呼ばれ、 Cross-Originリソース共有(CORS)の一部です。 。ブラウザはこれを特定のドメインからのリクエストが許可されているかどうかを確認するのように使用します
application/json
_コンテンツタイプを含むPOST
リクエストがあるとします。OPTIONS
リクエストを送信しますHTTP 200 OK
_応答を受け取った場合、ブラウザは実際のリクエストPOST
を送信します。ブラウザないプレフライトリクエストを送信する場合があります。これらはいわゆるシンプルリクエストであり、次の条件で使用されます。
- 許可されている方法の1つ:
GET
HEAD
POST
- ユーザーエージェントによって自動的に設定されるヘッダー(たとえば、接続、ユーザーエージェントなど)とは別に、手動で設定できるヘッダーは次のとおりです。
Accept
- _
Accept-Language
_- _
Content-Language
_- _
Content-Type
_(ただし、以下の追加要件に注意してください)DPR
Downlink
- _
Save-Data
_- _
Viewport-Width
_Width
- Content-Typeヘッダーに許可される値は、次のとおりです。
- _
application/x-www-form-urlencoded
_- _
multipart/form-data
_- _
text/plain
_- リクエストで使用される
XMLHttpRequestUpload
オブジェクトにイベントリスナーは登録されていません。これらは_XMLHttpRequest.upload
_プロパティを使用してアクセスされます。ReadableStream
オブジェクトはリクエストで使用されません。
このようなリクエストは直接送信され、サーバーはリクエストを正常に処理するか、CORSルールに一致しない場合はエラーで応答します。いずれの場合も、応答にはCORSヘッダー_Access-Control-Allow-*
_が含まれます。
ブラウザare実際のリクエストがシンプルリクエストの条件を満たさない場合、プリフライトリクエストを送信します。
application/xml
_や_application/json
_などのカスタムコンテンツタイプが使用されます。GET
、HEAD
またはPOST
以外であるPOST
メソッドは、_application/x-www-form-urlencoded
_、_multipart/form-data
_または_text/plain
_以外のコンテンツタイプです。preflightリクエストへの応答に次の属性があることを確認してください:
200 OK
_Access-Control-Allow-Origin: *
_(ワイルドカード_*
_は、任意のドメインからのリクエストを許可します。もちろん、任意の特定のドメインを使用して、ここでのアクセスを制限できます)反対側から、サーバーはCORSリクエストを拒否する次の属性を持つpre-flightリクエストに応答を送信するだけでよい:
2XX
_以外)200 OK
_)、ただしCORSヘッダーなし(例:_Access-Control-Allow-*
_)詳細については Mozilla Developer Networkのドキュメント または例 HTML5RocksのCORSチュートリアル を参照してください。
したがって、あなたのケースでは、適切なヘッダーが存在します--プリフライト応答のHTTPステータスコードが_200 OK
_または他の成功したもの(_2XX
_)。
APIにNODEサーバーを使用するAngular 2アプリの作成で非常によく似た問題が発生しました。
ローカルマシンで開発しているため、POSTアプリからAPIにAngularしようとすると、クロスオリジンヘッダーの問題が発生し続けました。
以下のように(ノードサーバーで)ヘッダーを設定するとGETリクエストで機能しましたが、私のPUTリクエストは空のオブジェクトをデータベースにポストし続けました。
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type,
Origin, Authorization, Accept, Client-Security-Token, Accept-
Encoding, X-Auth-Token, content-type');
Dawid Ferenczyの投稿 を読んだ後、PREFLIGHTリクエストがサーバーに空白のデータを送信していることがわかりました。そのため、DBエントリが空でした。そのため、NODE JSサーバーに次の行を追加しました。
if (req.method == "OPTIONS")
{
res.writeHead(200, {"Content-Type": "application/json"});
res.end();
}
したがって、私のサーバーはPREFLIGHT要求を無視し(そしてステータス200を返し、すべてがGroovyであることをブラウザーに通知します...)、そのようにして、実際の要求が通過し、実際のデータがDBにポストされます。
置くだけ
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("HTTP/1.1 200 ");
exit;}
あなたのサーバーサイドアプリの冒頭で、あなたは大丈夫でなければなりません。
スプリングブートアプリケーションの場合、corsリクエストを有効にするには、それぞれのコントローラーで@CrossOrigin(origins = "*", maxAge = 3600)
を使用します。