この記事では、CORS に基づいた WebApi Ajax クロスドメイン リクエストの解決策を主に紹介します。必要な友人は参照してください
概要
ASP.NET Web API を使用したことがある人なら誰でも、それが複雑ではないことを知っています。 . 構成ファイル、単純な ApiController と必要なアクションが機能します。ただし、API を使用する場合、クロスドメイン リクエストの問題が常に発生します。特に今日ではさまざまな APP が急増しており、API に対するクロスドメイン リクエストは避けられません。
デフォルトでは、CSRF クロスサイト フォージェリ攻撃 (または JavaScript の同一生成元ポリシー) を防ぐために、Web ページが別のドメインからデータを取得する場合は制限されます。この制限を突破する方法はいくつかありますが、これはよく知られた JSONP です。もちろん、これは多くの解決策の 1 つにすぎません。JSONP は GET リクエストのみをサポートしているため、今日の複雑なビジネスのニーズを満たすことはできません。 CORS (Cross Origin Resource Sharing https://www.w3.org/wiki/CORS) クロスドメイン リソース共有は、サーバーがクロスドメイン制限を緩和し、ヘッダーに基づいて制限を切り替えることを可能にする新しいヘッダー仕様です。クロスドメインリクエストを制限しません。重要なことは、すべての http リクエスト メソッドをサポートしていることです。
Question
XMLHttpRequest クロスドメイン POST または GET リクエストの場合、リクエスト メソッドは自動的に OPTIONS の質問になります。
CORS (クロスオリジンリソースシェア) 仕様の存在により、ブラウザは最初にオプションスニフを送信し、同時にヘッダーにオリジンを含めて、クロスドメインリクエストの許可があるかどうかを判断します。サーバーは、ブラウザーのアクセス制御許可オリジンの値で応答します。オリジンと一致する場合、サーバーがプログラムにクロスドメインへのアクセスを許可している場合でも、オプションリクエストがサポートされていない場合は、ポストリクエストが正式に送信されます。リクエストは無効になります。
理由
セキュリティ上の理由から、ブラウザはプリフライトリクエストの透過的なサーバー検証メカニズムを使用して、カスタムヘッダー、GET または POST 以外のメソッド、およびさまざまなタイプのテーマコンテンツを使用する開発者をサポートします。つまり、オプションリクエストはを最初に送信し、
リクエストを正しく送信する (許可する) かどうかをサーバーに問い合わせて、リクエストを送信しても安全であることを確認します。
OPTIONS が表示される状況は一般的に次のとおりです:
1. 非 GET、POST リクエスト
2. POST リクエストのコンテンツ タイプは、従来の 3 つではありません: application/x-www-form-urlencoded (HTTP を使用して送信) POST メソッド form)、multipart/form-data (上記と同じですが、主にフォーム送信時にファイルがアップロードされるときに使用されます)、text/plain (プレーン テキスト)
3. POST リクエストのペイロードは text/html です。
4. カスタムヘッダーの設定
OPTIONS リクエストヘッダーには、Origin、Access-Control-Request-Method、Access-Control-Request-Headers が含まれます。このリクエストを送信した後、サーバーは通信するために次のヘッダーを設定できます。ブラウザを使用してリクエストを許可するかどうかを決定します。
Access-Control-Allow-Origin、Access-Control-Allow-Method、Access-Control-Allow-Headers
ソリューション
このメソッドは強力で、ASP.NET Web の複雑なクロスドメイン要求を解決できます。複雑なヘッダー情報、本文コンテンツ、および認証検証情報を運ぶ API
方法 1
public class CrosHandler:DelegatingHandler { private const string Origin = "Origin"; private const string AccessControlRequestMethod = "Access-Control-Request-Method"; private const string AccessControlRequestHeaders = "Access-Control-Request-Headers"; private const string AccessControlAllowOrign = "Access-Control-Allow-Origin"; private const string AccessControlAllowMethods = "Access-Control-Allow-Methods"; private const string AccessControlAllowHeaders = "Access-Control-Allow-Headers"; private const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials"; protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { bool isCrosRequest = request.Headers.Contains(Origin); bool isPrefilightRequest = request.Method == HttpMethod.Options; if (isCrosRequest) { Task<HttpResponseMessage> taskResult = null; if (isPrefilightRequest) { taskResult = Task.Factory.StartNew<HttpResponseMessage>(() => { HttpResponseMessage response = new HttpResponseMessage(System.Net.HttpStatusCode.OK); response.Headers.Add(AccessControlAllowOrign, request.Headers.GetValues(Origin).FirstOrDefault()); string method = request.Headers.GetValues(AccessControlRequestMethod).FirstOrDefault(); if (method != null) { response.Headers.Add(AccessControlAllowMethods, method); } string headers = string.Join(", ", request.Headers.GetValues(AccessControlRequestHeaders)); if (!string.IsNullOrWhiteSpace(headers)) { response.Headers.Add(AccessControlAllowHeaders, headers); } response.Headers.Add(AccessControlAllowCredentials, "true"); return response; }, cancellationToken); } else { taskResult = base.SendAsync(request, cancellationToken).ContinueWith<HttpResponseMessage>(t => { var response = t.Result; response.Headers.Add(AccessControlAllowOrign, request.Headers.GetValues(Origin).FirstOrDefault()); response.Headers.Add(AccessControlAllowCredentials, "true"); return response; }); } return taskResult; } return base.SendAsync(request, cancellationToken); } }
使用方法、
protected void Application_Start() { IOCConfig.RegisterAll(); AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); GlobalConfiguration.Configuration.MessageHandlers.Add(new CrosHandler()); }
方法 2
Global.asax ファイルに次の設定を追加します
設定ファイル, この方法は簡単で、単純なクロスドメインリクエストに対処するためのものです<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST,OPTIONS" /> </customHeaders> </httpProtocol> <system.webServer>
関連記事: Ajaxリクエストバイナリストリーム処理(
ajaxajax🎜Ajaxでのレスポンスについてバックグラウンドでのデータ送信に関する問題 (コード、詳細な分析を含む) 🎜🎜以上がCORS に基づく WebApi Ajax クロスドメイン リクエスト ソリューションの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。