Maison  >  Article  >  interface Web  >  Implémentation d'une solution de requêtes inter-domaines WebApi Ajax basée sur CORS

Implémentation d'une solution de requêtes inter-domaines WebApi Ajax basée sur CORS

亚连
亚连original
2018-05-22 09:24:041908parcourir

Cet article présente principalement la solution à la requête inter-domaines WebApi Ajax basée sur CORS. Les amis dans le besoin peuvent se référer à ce qui suit

Aperçu

.

Tous ceux qui ont utilisé l'API Web ASP.NET savent qu'il n'y a pas de fichier de configuration compliqué, un simple ApiController plus l'action requise peuvent fonctionner. Cependant, lorsque vous utilisez des API, vous rencontrerez toujours le problème des requêtes inter-domaines. Surtout aujourd'hui, avec la prolifération de diverses applications, les requêtes inter-domaines pour les API sont inévitables.

Par défaut, afin d'empêcher les attaques de contrefaçon intersites CSRF (ou la politique de même origine de JavaScript), une page Web sera restreinte lorsqu'elle obtiendra des données d'un autre domaine. Il existe plusieurs moyens de contourner cette limitation, à savoir le célèbre JSONP. Bien entendu, ce n'est qu'une solution parmi tant d'autres. Puisque JSONP ne prend en charge que les requêtes GET, il ne peut plus répondre aux besoins des entreprises complexes d'aujourd'hui. Le partage de ressources inter-domaines CORS (Cross Origin Resource Sharing https://www.w3.org/wiki/CORS) est une nouvelle spécification d'en-tête qui permet au serveur d'assouplir les restrictions inter-domaines et de changer de restrictions en fonction des en-têtes. Ne restreignez pas les requêtes inter-domaines. L'important est qu'il prend en charge toutes les méthodes de requête http.

Problème

Requête POST ou GET inter-domaines XMLHttpRequest, la méthode de requête deviendra automatiquement un problème OPTIONS.

En raison de l'existence de la spécification CORS (cross origin resource share), le navigateur enverra d'abord un reniflage d'options, et en même temps, l'en-tête apportera l'origine pour déterminer s'il y a une requête inter-domaines. autorisation. Le serveur répondra avec la valeur de contrôle d'accès autoriser l'origine, pour que le navigateur corresponde à l'origine, la demande de publication sera officiellement envoyée même si le serveur autorise l'accès à plusieurs domaines. la demande d'options n'est pas prise en charge, la demande mourra.

Raison

Pour des raisons de sécurité, le navigateur prend en charge le mécanisme transparent de vérification du serveur de Preflighted Request pour aider les développeurs à utiliser des en-têtes personnalisés, GET ou des méthodes autres que POST et différents types de contenu de sujet, c'est-à-dire qu'une demande d'options sera envoyée en premier,
demandez au serveur s'il autorisera correctement la demande et assurez-vous que l'envoi de la demande est sûr.

Les situations dans lesquelles OPTIONS apparaissent sont généralement :

1. Non-GET, requête POST

2 Le type de contenu de la requête POST n'est pas les trois : application conventionnelles. /x- www-form-urlencoded (formulaire soumis à l'aide de la méthode HTTP POST), multipart/form-data (identique à ci-dessus, mais principalement utilisé lors du téléchargement de fichiers lors de la soumission d'un formulaire), text/plain (texte brut)

3. La charge utile de la requête POST est text/html 

4. Définir des en-têtes personnalisés

L'en-tête de requête OPTIONS comprendra les en-têtes suivants : Origin, Access-Control-Request-Method. , Access-Control-Request-Headers Après avoir envoyé cette demande, le serveur peut définir les en-têtes suivants pour communiquer avec le navigateur afin de déterminer s'il doit autoriser la demande.
Access-Control-Allow-Origin, Access-Control-Allow-Method, Access-Control-Allow-Headers

Solution

Cette méthode est puissante et peut résoudre des requêtes inter-domaines complexes de l'API Web ASP.NET, contenant des informations d'en-tête complexes, du contenu du corps et des informations de vérification d'autorisation

Méthode 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);
 }
}

Utilisation : ajoutez

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());
}

au fichier Global.asax. Méthode 2 : ajoutez la configuration suivante au fichier de configuration

. simple et peut gérer de simples requêtes inter-domaines

<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>

Ce qui précède est ce que j'ai compilé pour tout le monde. J'espère que cela sera utile à tout le monde à l'avenir.

Articles associés :

Ajax demande un flux binaire pour le traitement (ajaxtéléchargement asynchrone de fichiers)

Django framework Comment utiliser la méthode post de ajax (tutoriel image et texte)

À propos du problème de transmission de données en arrière-plan via une réponse en Ajax (y compris le code, analyse détaillée)

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn