jQuery Ajax i IE

19 czerwca 2009, 00:13

KomentarzeKomentarze: 1 KategorieKategorie: asp.netmvcjquery

Dosyć intensywnie w swoich projektach używam wywołań $.get i $.post dostępnych z poziomu jQuery. Niestety IE (w moim przypadku IE7) zawsze wykonuje żądanie do serwera jako POST. To skutkuje tym, że nie możemy mieć przykładowo dwóch metod Update rozróżnionych tylko metodą wywołania. Dziś szukałem przyczyny i rozwiązania tego problemu, ale niestety nie udało mi się znaleźć.

Dlatego postanowiłem napisać własny atrybut, który będzie sprawdzał czy żądanie pochodzi z jQuery oraz czy żądanie powinno być wywołane jako POST czy GET.

W tym celu w ustawieniach każdego wywołania Ajax po stronie jQuery musiałem dodać własny nagłówek, po którym będę rozpoznawał jaką metodą jest wykonywane wywołanie.

   1:  $().ajaxSend(function(event, request, settings) {
   2:      request.setRequestHeader("X-Requested-Method", settings.type)
   3:  });

Podpiąłem się pod zdarzenie ajaxSend, gdzie dodaję nagłówek do każdego żądania, a jako wartość wstawiana jest metoda wywołania. Kiedy wykonamy metodę $.get to wartość nagłówka będzie GET i analogicznie dla metody $.post.

Teraz po stronie serwera musimy sprawdzić ten nagłówek i zadecydować czy dana akcja może zostać wywołana. Napisałem do tego własny atrybut AcceptAjaxRequest.

 

   1:  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
   2:  public sealed class AcceptAjaxRequestAttribute : ActionMethodSelectorAttribute
   3:  {
   4:      private const string _x_requested_with = "X-Requested-With";
   5:      private const string _x_requested_method = "X-Requested-Method";
   6:   
   7:      public AcceptAjaxRequestAttribute()
   8:      {
   9:          Verb = null;
  10:      }
  11:   
  12:      public AcceptAjaxRequestAttribute(HttpVerbs verb)
  13:      {
  14:          Verb = verb;
  15:      }
  16:   
  17:      private HttpVerbs? Verb { get; set; }
  18:   
  19:      public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
  20:      {
  21:          bool isAjaxRequest = IsAjaxRequest(controllerContext);
  22:          
  23:          if (!Verb.HasValue)
  24:          {
  25:              return isAjaxRequest;
  26:          }
  27:   
  28:          return isAjaxRequest && IsAjaxRequestedMethod(controllerContext);
  29:      }
  30:   
  31:      private bool IsAjaxRequestedMethod(ControllerContext controllerContext)
  32:      {
  33:          bool hasAjaxRequestedMethod = controllerContext.HttpContext.Request.Headers.AllKeys.Contains<string>(
  34:             _x_requested_method,
  35:             StringComparer.InvariantCultureIgnoreCase);
  36:   
  37:          if (hasAjaxRequestedMethod)
  38:          {
  39:              return controllerContext.HttpContext.Request.Headers[_x_requested_method].Equals(
  40:                  this.Verb.ToString(),
  41:                  StringComparison.InvariantCultureIgnoreCase);
  42:          }
  43:          return false;
  44:      }
  45:   
  46:      private bool IsAjaxRequest(ControllerContext controllerContext)
  47:      {
  48:          return controllerContext.HttpContext.Request.Headers.AllKeys.Contains<string>(
  49:             _x_requested_with,
  50:             StringComparer.InvariantCultureIgnoreCase);
  51:      }
  52:  }

Atrybut ten robi to samo co atrybut Microsoft.Web.Mvc.AcceptAjax, ale dodatkowo sprawdza nasz nowy nagłówek.

Przykładowe użycie wygląda nastepująco:

   1:  [Softio.Commons.Mvc.AcceptAjaxRequest(HttpVerbs.Get)]
   2:  public ActionResult Update(int id)
   3:  {
   4:      return View();
   5:  }
   6:   
   7:  [Softio.Commons.Mvc.AcceptAjaxRequest(HttpVerbs.Post)]
   8:  public ActionResult Update(int id, string name)
   9:  {
  10:      // zapisujemy dane
  11:      return View();
  12:  }

Podsumowując

Posługując się tą kombinacją obchodzimy problem wysyłania żądania do serwera metodą POST w Internet Explorerze mimo iż chcieliśmy wykonać żądanie GET. Żądanie $.get w IE oczywiście jest POSTe, ale możemy zareagować na nie, jakby było GETem i nasz kod aplikacji będzie poprawny w IE jak i tych dobrze działających przeglądarkach.

 

Ten artykuł jest widoczny także na: ZINE.NET

Jeśli spodobał Ci się ten artykuł, to podziel się tą informacją z innymi.

Gravatar
wypożyczalnie quadów
2010-03-27 18:21

Artykuł bardzo pomocny i przydał mi się bardzo. Dzięki

Dodaj komentarz Dodaj komentarz

Twój email (niepublikowany/opcjonalnie):

Twoja strona (opcjonalnie):

Imię i nazwisko/nick (wymagane):

Treść (wymagane):

Chcę być poinformowany o kolejnych komentarzach:

Te pola zostaw puste

Uwaga! Zastrzegam sobie prawo do usuwania obraźliwych i wulgarnych komentarzy.