私はWeb APIを構築しています。 POSTにChromeを使用し、APIにGETを実行するたびに、実際のリクエストの前にOPTIONSリクエストが送信されることがあり、これは非常に面倒です。現在私はサーバーにOPTIONSリクエストを無視させます。今私の質問は、サーバーの負荷を倍増するためにOPTIONSリクエストを送信するのが良いことですか?ブラウザがOPTIONSリクエストを送信しないようにする方法はありますか?
編集2018-09-13 :このフライト前のリクエストと、このレスポンスの最後にそれを回避する方法についてのいくつかの精度を追加しました。
OPTIONS
リクエストはCross-Origin resource sharing (CORS)
でpre-flight
リクエストと呼んでいます。
あなたが特定の状況で異なる起源にまたがって要求をするとき、それらは必要です。
この飛行前の要求は、行われている要求がサーバーによって信頼されていることを確認するための安全対策として、一部のブラウザーによって行われます。サーバが、リクエストで送信されたメソッド、Origin、およびヘッダが安全に動作していることを理解していることを意味します。
クロスオリジンリクエストを実行しようとしているときはいつでも、サーバはこれらのリクエストを無視せずに処理する必要があります。
良いリソースはここにあります http://enable-cors.org/ /
快適にするためにこれらを処理する方法は、OPTIONS
メソッドを持つすべてのパスに対して、サーバーがこのヘッダーを含む応答を送信するようにすることです。
Access-Control-Allow-Origin: *
これはブラウザにサーバがどんなOriginからの要求にも答えても構わないと思っていることを伝えます。
サーバーにCORSサポートを追加する方法の詳細については、以下のフローチャートを参照してください。
http://www.html5rocks.com/static/images/cors_server_flowchart.png
編集2018-09-13
MDNドキュメント :で説明されているように、CORSのOPTIONS
リクエストはいくつかのケースでのみ引き起こされます。
一部の要求では、CORSのプリフライトは発生しません。この記事ではこれらを「単純要求」と呼びますが、Fetch仕様(CORSを定義する)ではこの用語は使用されていません。 CORSプリフライトをトリガーしない要求(いわゆる「単純要求」)は、以下のすべての条件を満たすものです。
許可されているメソッドは次のとおりです。
- GET
- HEAD
- POST
ユーザエージェントによって自動的に設定されるヘッダ(例えば、Connection、User-Agent、またはFetch仕様で「禁止されたヘッダ名」として定義された名前を持つ他のヘッダなど)を除いて、許可される唯一のヘッダ手動で設定されるのは、Fetch仕様で「CORSセーフリストの要求ヘッダー」として定義されているものです。
- 受け入れる
- 受け入れ言語
- コンテンツ言語
- コンテンツタイプ(ただし、以下の追加要件に注意してください)
- 北朝鮮
- ダウンリンク
- データ保存
- ビューポート幅
- 幅
Content-Typeヘッダーに許可されている唯一の値は次のとおりです。
- application/x-www-form-urlencoded
- マルチパート/フォームデータ
- テキスト/プレーン
リクエストで使用されるXMLHttpRequestUploadオブジェクトには、イベントリスナーは登録されていません。これらはXMLHttpRequest.uploadプロパティを使ってアクセスされます。
リクエストでReadableStreamオブジェクトは使用されません。
この問題を見てきましたが、以下に、この問題に対する私の結論と解決策を示します。
CORS戦略によれば (強く読むことを強くお勧めします)必要であればブラウザにOPTIONSリクエストの送信を強制的に停止させることはできません。
これを回避する方法は2つあります。
Access-Control-Max-Age
を設定します単純なクロスサイトリクエストは、以下のすべての条件を満たすものです。
許可されているメソッドは次のとおりです。
ユーザエージェントによって自動的に設定されるヘッダ(例えば、接続、ユーザエージェントなど)とは別に、手動で設定することが許される唯一のヘッダは以下の通りである。
Content-Typeヘッダーに許可されている唯一の値は次のとおりです。
単純なリクエストではフライト前のOPTIONSリクエストは発生しません。
OPTIONSリクエストにAccess-Control-Max-Age
を設定して、期限が切れるまでアクセス権を確認しないようにすることができます。
Access-Control-Max-Ageは、別のプリフライト要求を送信せずにプリフライト要求への応答をキャッシュできる期間を秒単位で指定します。
Access-Control-Max-Age
の最大秒数は600
で、10分です。 chrome source codeAccess-Control-Max-Age
は毎回1つのリソースに対してのみ機能します。例えば、同じURLパスを持つGET
リクエストは異なるクエリは異なるリソースとして扱われます。そのため、2番目のリソースへのリクエストはまだプリフライトリクエストをトリガーします。プレフライトされたOPTIONSリクエストの実際の必要性については、この回答を参照してください。 CORS - プリフライトリクエストを導入する動機は何ですか?
OPTIONSリクエストを無効にするには、ajaxリクエストに対して以下の条件を満たす必要があります。
application/x-www-form-urlencoded
、multipart/form-data
、またはtext/plain
のいずれかになります。参照: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
デバッグコンソールを開いてDisable Cache
オプションをオンにすると、プリフライトリクエストは常に送信されます(つまり、各リクエストの前に)。キャッシュを無効にしないと、フライト前のリクエストは(サーバーごとに)1回だけ送信されます。
はい、それはオプションの要求を回避することが可能です。オプションリクエストは、データを別のドメインに送信(投稿)するときのプリフライトリクエストです。ブラウザのセキュリティ問題です。しかし、我々は別の技術を使うことができます:iframeトランスポート層。 CORSの設定を忘れて既製のソリューションを使用することを強くお勧めします。
ここで見てみましょう: https://github.com/jpillora/xdomain
そして実用的な例: http://jpillora.com/xdomain/
以前の記事ですでに述べたように、OPTIONS
リクエストは理由があります。サーバーからの応答時間が長い場合(海外接続など)に問題がある場合は、ブラウザーにプリフライトリクエストをキャッシュさせることもできます。
サーバーにAccess-Control-Max-Age
ヘッダーを付けて応答させ、同じエンドポイントに送信される要求に対してはプリフライト要求がキャッシュされ、もう発生しないようにします。
それが存在する理由を理解しているが認証なしでOPTIONS呼び出しを処理しないAPIにアクセスする必要がある開発者のために、私は一時的な答えを必要と稼働中です。
SafariではCORSを、MacではChromeを無効にできることがわかりました。
Chrome:Chromeを終了し、端末を開いて次のコマンドを貼り付けます:open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari: Safariで同一オリジンポリシーを無効にする
あなたがSafariのsame-originポリシー(私は9.1.1を持っています)を無効にしたいのなら、あなたは開発者メニューを有効にする必要があるだけです。
私はこの問題を次のように解決しました。
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && ENV == 'devel') {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header("HTTP/1.1 200 OK");
die();
}
開発専用です。これで私は9msと500msではなく8sと500msを待っています。本番用のJSアプリは本番用のマシンと同じマシン上にあるので、OPTIONS
はありませんが、開発は私のローカルです。
できませんがJSONPを使用したCORSを避けることができます。
一日半費やして同様の問題を解決しようとしたところ、 _ iis _ と関係があることがわかりました。
私のWeb APIプロジェクトは次のように設定されています。
// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
//...
}
CORS固有の設定オプションがありませんでした web.config> system.webServerノードで、多数の投稿で見たことがあります
global.asaxまたはデコレータとしてのコントローラにCORS固有のコードがない
問題は アプリプールの設定 です。
マネージドパイプラインモード はクラシック( 統合 )に設定され、 Identity はネットワークサービス( ApplicationPoolIdentity に変更)に設定されました。
これらの設定を変更して(そしてアプリプールを更新して)それを修正しました。