2011-01-03 32 views
33

w aplikacji ASP.NET MVC używam jQuery do wysyłania danych na kliknięcie przycisku:jQuery żądania post (nie AJAX)

<button onclick="addProducts()">Add products</button> 
.... 
$.post('<%= Url.Action("AddToCart", "Cart") %>', 
      { 
       ... 
       returnUrl: window.location.href 
      }); 

W „AddToCart” działania „koszyka” kontrolera używam przekierowanie do inny widok po zaksięgowaniu:

public RedirectToRouteResult AddToCart(..., string returnUrl) 
    { 
     ... 
     return RedirectToAction("Index", new { returnUrl });    
    } 

Wszystko jest w porządku, z wyjątkiem tego przekierowania. Po opublikowaniu pozostaję na tej samej stronie. Podejrzewam, że jest to spowodowane żądaniem typu "POST" typu AJAX.

Jak rozwiązać problem z żądaniem POST jQuery blokującym przekierowanie?

+0

Czy próbujesz przekierować na tę samą stronę, która inicjuje żądanie Ajax? – Corneliu

Odpowiedz

84

stworzyłem $.form(url[, data[, method = 'POST']]) funkcję, która tworzy ukrytą formę, zapełnia ją z określonymi danymi i przywiązuje go do <body>. Oto kilka przykładów:

$.form('/index') 

<form action="/index" method="POST"></form> 
$.form('/new', { title: 'Hello World', body: 'Foo Bar' }) 

<form action="/index" method="POST"> 
    <input type="hidden" name="title" value="Hello World" /> 
    <input type="hidden" name="body" value="Foo Bar" /> 
</form> 
$.form('/info', { userIds: [1, 2, 3, 4] }, 'GET') 

<form action="/info" method="GET"> 
    <input type="hidden" name="userIds[]" value="1" /> 
    <input type="hidden" name="userIds[]" value="2" /> 
    <input type="hidden" name="userIds[]" value="3" /> 
    <input type="hidden" name="userIds[]" value="4" /> 
</form> 
$.form('/profile', { sender: { first: 'John', last: 'Smith', postIds: null }, 
        receiver: { first: 'Foo', last: 'Bar', postIds: [1, 2] } }) 

<form action="/profile" method="POST"> 
    <input type="hidden" name="sender[first]" value="John"> 
    <input type="hidden" name="sender[last]" value="Smith"> 
    <input type="hidden" name="receiver[first]" value="John"> 
    <input type="hidden" name="receiver[last]" value="Smith"> 
    <input type="hidden" name="receiver[postIds][]" value="1"> 
    <input type="hidden" name="receiver[postIds][]" value="2"> 
</form> 

Z .submit() metody jQuery można utworzyć i przesłać formularz z prostego wyrażenia:

$.form('http://stackoverflow.com/search', { q: '[ajax]' }, 'GET').submit(); 

Oto definicja funkcji:

jQuery(function($) { $.extend({ 
    form: function(url, data, method) { 
     if (method == null) method = 'POST'; 
     if (data == null) data = {}; 

     var form = $('<form>').attr({ 
      method: method, 
      action: url 
     }).css({ 
      display: 'none' 
     }); 

     var addData = function(name, data) { 
      if ($.isArray(data)) { 
       for (var i = 0; i < data.length; i++) { 
        var value = data[i]; 
        addData(name + '[]', value); 
       } 
      } else if (typeof data === 'object') { 
       for (var key in data) { 
        if (data.hasOwnProperty(key)) { 
         addData(name + '[' + key + ']', data[key]); 
        } 
       } 
      } else if (data != null) { 
       form.append($('<input>').attr({ 
        type: 'hidden', 
        name: String(name), 
        value: String(data) 
       })); 
      } 
     }; 

     for (var key in data) { 
      if (data.hasOwnProperty(key)) { 
       addData(key, data[key]); 
      } 
     } 

     return form.appendTo('body'); 
    } 
}); }); 
+2

Jeremy, dzięki za udostępnienie, +1 – rem

+0

Cudownie! Nie wiem, czy to dobra praktyka, ale uwielbiam to rozwiązanie. +1 – Samuel

+0

Dlaczego nie wywoływać funkcji .remove() po .submit(), aby zapobiec kilku ukrytym formularzom podczas wywoływania funkcji kilka razy? – Samuel

9

$.post to połączenie AJAX.

Najlepszym wyjściem jest sprawienie, by przycisk uruchamiał formularz i wystarczy go przesłać metodą post.

Alternatywą byłoby powtórzenie twojego nowego adresu URL z serwera, ale to pokonuje punkt AJAX.

3

Wygląda jak próbujesz dodać produkty do koszyka, a następnie przekierować do bieżącej strony. Domyślam się, że właśnie w ten sposób aktualizujesz efekt wizualny swojego koszyka. Sugerowałbym dodanie modułu obsługi sukcesu do twojego .post, a następnie przekierowanie do bieżącej strony. Jeśli wystąpi błąd na serwerze, możesz odesłać zserializowany błąd i obsłużyć go po stronie klienta.

function addProducts() { 
    $.post('<%= Url.Action("AddToCart", "Cart") %>',{ 
     returnUrl: window.location.href 
    }, function(data){ 
     window.location.href = window.location.href 
    }); 
} 

Spowoduje to odświeżenie bieżącej strony po opublikowaniu produktów.

Oto skrzypce dla odniesienia: http://jsfiddle.net/brentmn/B4P6W/3/

1

Jeśli robisz pełne przekierowanie po poście, to dlaczego ona z Ajax? Powinieneś być w stanie wykonać transakcyjny test POST tutaj i przekierować go pomyślnie.

Jeśli naprawdę chcą ajax żądania przejść i nadal przekierowanie, bardzo łatwe i nieinwazyjne sposobem na to byłoby zwrócić JavascriptResult ze swojego działania zamiast RedirectResult:

return JavaScript("window.location = " + returnUrl);