Jak przesłać formularz HTML bez przekierowania

101

Jeśli mam taki formularz,

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm"> ... </form>

jak mogę to przesłać bez przekierowywania do innego widoku przez JavaScript / jQuery?

Czytałem mnóstwo odpowiedzi ze Stack Overflow, ale wszystkie z nich przekierowują mnie do widoku zwróconego przez funkcję POST.

Duke Nuke
źródło
Chcesz prośbę o XHR (AJAX)
Sterling Archer
2
XHR / AJAX to jeden sposób - twierdzi ona w słupek i dostaje odpowiedź za kulisy, więc przeglądarka nie opuszcza stronę, to jest on. Innym sposobem jest przekierowanie po stronie serwera po przetworzeniu wiadomości, co zależy od używanej technologii serwerowej.
Stephen P,
@StephenP Używam ASP.NET MVC 5.1.
Duke Nuke
@Duke, mówię tylko, że istnieje więcej niż jedno podejście (AJAX vs. przekierowanie serwera), a wybór zależy od Twoich potrzeb. Nowoczesne strony najprawdopodobniej będą chciały używać Ajax. Należy również zauważyć, że wszystkie te odpowiedzi mówią Ci potrzebne jQuery - jQuery jest świetna, ale nie w rzeczywistości, inne sposoby, aby zrobić ajax ... chociaż ja rzeczywiście używać jQuery siebie.
Stephen P
1
Mój sposób jest prosty, czysty i elegancki, a to tylko 2 linie kodu. Nie używa skryptów i działa w HTML4 i nowszych wersjach, nawet jeśli JavaScript jest wyłączony.
Issa Chanzi

Odpowiedzi:

75

Aby osiągnąć to, co chcesz, musisz użyć jQuery Ajax, jak poniżej:

$('#myForm').submit(function(e){
    e.preventDefault();
    $.ajax({
        url: '/Car/Edit/17/',
        type: 'post',
        data:$('#myForm').serialize(),
        success:function(){
            // Whatever you want to do after the form is successfully submitted
        }
    });
});

Spróbuj też tego:

function SubForm(e){
    e.preventDefault();
    var url = $(this).closest('form').attr('action'),
    data = $(this).closest('form').serialize();
    $.ajax({
        url: url,
        type: 'post',
        data: data,
        success: function(){
           // Whatever you want to do after the form is successfully submitted
       }
   });
}

Ostateczne rozwiązanie

To działało bez zarzutu. Nazywam tę funkcję fromHtml.ActionLink(...)

function SubForm (){
    $.ajax({
        url: '/Person/Edit/@Model.Id/',
        type: 'post',
        data: $('#myForm').serialize(),
        success: function(){
            alert("worked");
        }
    });
}
Amin Jafari
źródło
To działało świetnie, problem polega na tym, że nie chcę, aby był automatycznie (zawsze) przesyłany w ten sposób. Chciałbym mieć funkcję z nazwą, która będzie robić to, co zamieściłeś w swojej odpowiedzi. Mogę więc wywołać go ręcznie, kiedy chcę, aby wysłać formularz. Jak poniżej mogę podać nazwę funkcji do wywołania. @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke
To zadziałało:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke,
Z jakiegoś powodu twoje drugie rozwiązanie nie zadziałało, ale to, które zamieściłem w ostatnim komentarzu, zadziałało. Dodam swoje rozwiązanie do Twojego postu, bo tylko dzięki Tobie mogłem to osiągnąć.
Duke Nuke
1
druga też musi działać, może być coś innego, ale jeśli znalazłeś rozwiązanie, nie musimy teraz iść tą drogą! cieszę się, że pomogło;)
Amin Jafari
Dzięki tej odpowiedzi pomogła mi również wstawić niestandardowy tekst w miejsce formularza po przesłaniu
Anupam
123

Możesz to osiągnąć, przekierowując formularz actiondo niewidocznego <iframe>. Nie wymaga JavaScript ani żadnego innego typu skryptów.

<iframe name="dummyframe" id="dummyframe" style="display: none;"></iframe>

<form action="submitscript.php" target="dummyframe">
    <!-- Form body here -->
</form>
Issa Chanzi
źródło
1
To jest świetne. Ale jak mogę coś zrobić po przesłaniu formularza? tj. pola tekstowe formularza będą musiały być puste, fokus wróci do pierwszego pola itd.?
Pranjal Choladhara
2
Jest taki javascript, który może to zrobić. Wystarczy zmienić <input type='submit'..., aby <input type='reset'dodaćonclick='document.forms["myForm"].submit();'>
Issa Chanzi
Piękna odpowiedź! Działa świetnie
Cybrus
1
Uważaj, prawdopodobnie ponownie załadujesz stronę, na której znajduje się Twój formularz, do elementu iframe, co może powodować problemy z wydajnością, jeśli tworzysz aplikację lub dużą witrynę.
Alexandre Daubricourt
24

Umieść ukryty iFrameu dołu strony i targetw swoim formularzu:

<iframe name="hiddenFrame" width="0" height="0" border="0" style="display: none;"></iframe>

<form action="/Car/Edit/17" id="myForm" method="post" name="myForm" target="hiddenFrame"> ... </form>

Szybko i łatwo. Należy pamiętać, że chociaż targetatrybut jest nadal szeroko obsługiwany (i obsługiwany w HTML5), został wycofany w HTML 4.01.

Więc naprawdę powinieneś używać Ajax, aby być przyszłościowym.

Steven Black
źródło
Według MDN to zachowanie targetjest całkowicie prawidłowe, więc AJAX jest nadal opcjonalny.
Daniel De León,
23

Ponieważ wszystkie aktualne odpowiedzi używają jQuery lub trików z iframe, doszedłem do wniosku, że nie ma nic złego w dodaniu metody za pomocą zwykłego JavaScript:

function formSubmit(event) {
  var url = "/post/url/here";
  var request = new XMLHttpRequest();
  request.open('POST', url, true);
  request.onload = function() { // request successful
  // we can use server response to our request now
    console.log(request.responseText);
  };

  request.onerror = function() {
    // request failed
  };

  request.send(new FormData(event.target)); // create FormData from form that triggered event
  event.preventDefault();
}

// and you can attach form submit event like this for example
function attachFormSubmitEvent(formId){
  document.getElementById(formId).addEventListener("submit", formSubmit);
}
Ethuil UI
źródło
2
Dziękuję bardzo!
Joshua Evans
Uchylam ci kapelusz. Spędziłem godziny, próbując dowiedzieć się, jak zmusić jquery do wysłania formularza do zaplecza nginx z parametrem contentType = false i zawsze otrzymuję jako wynik 415. To było jedyne rozwiązanie, które znalazłem, które rozwiązało mój konkretny problem.
user12066
8

Okej, nie powiem ci, jak to zrobić w magiczny sposób, ponieważ nie ma. Jeśli masz ustawiony atrybut akcji dla elementu formularza, przekieruje.

Jeśli nie chcesz, aby przekierowywał, po prostu nie ustawiaj żadnej akcji i ustaw onsubmit="someFunction();"

W swoim someFunction()robisz, co chcesz (z AJAXem lub nie) i na końcu dodajesz, return false;aby powiedzieć przeglądarce, aby nie wysyłała formularza ...

Anshu Dwibhashi
źródło
1
Jest na to magiczny sposób. Ustaw atrybut docelowy, aby formularz przekierowywał do innego miejsca niż bieżąca ramka. Jeśli dodasz niewidoczny element iframe na takie rzeczy na swoich stronach. To całkiem proste.
Issa Chanzi
5

Potrzebujesz Ajax, aby to się stało. Coś takiego:

$(document).ready(function(){
    $("#myform").on('submit', function(){
        var name = $("#name").val();
        var email = $("#email").val();
        var password = $("#password").val();
        var contact = $("#contact").val();

        var dataString = 'name1=' + name + '&email1=' + email + '&password1=' + password + '&contact1=' + contact;
        if(name=='' || email=='' || password=='' || contact=='')
        {
            alert("Please fill in all fields");
        }
        else
        {
            // Ajax code to submit form.
            $.ajax({
                type: "POST",
                url: "ajaxsubmit.php",
                data: dataString,
                cache: false,
                success: function(result){
                    alert(result);
                }
           });
        }
        return false;
    });
});
Bojan Petkovski
źródło
5
Czy jest jakiś szczególny powód, dla którego nie wciskasz tego kodu źródłowego? Wygląda na kod z lat sześćdziesiątych przed wynalezieniem C. Myślałem, że już z tym skończyliśmy.
Alfe
3

Jednoliniowe rozwiązanie od 2020 r., Jeśli dane nie mają być wysyłane jako multipart/form-datalub application/x-www-form-urlencoded:

<form onsubmit='return false'>
    <!-- ... -->           
</form>
Alexandre Daubricourt
źródło
3
Jeśli połączysz to z OP action="...", skutecznie zapobiega to zmianie strony, ale także zapobiega przesyłaniu danych przez sieć.
Kev
@Kev Osobiście wysyłam swoje dane przez JS XHR, dlatego nie chcę przekierowania strony, bo to aplikacja JS
Alexandre Daubricourt
@Kev Przepraszam, że powinienem o tym wspomnieć
Alexandre Daubricourt
2

Zobacz postfunkcję jQuery .

Utworzyłbym przycisk, ustawiłbym onClickListener( $('#button').on('click', function(){});) i wysłałbym dane w funkcji.

Zobacz także preventDefaultfunkcję jQuery!

Nagy Vilmos
źródło
1

Pożądany efekt można również osiągnąć, przenosząc przycisk przesyłania poza formularz, jak opisano tutaj:

Zapobiegaj przeładowywaniu strony i przekierowywaniu w formularzu przesłania ajax / jquery

Lubię to:

<form id="getPatientsForm">
    Enter URL for patient server
    <br/><br/>
    <input name="forwardToUrl" type="hidden" value="/WEB-INF/jsp/patient/patientList.jsp" />
    <input name="patientRootUrl" size="100"></input>
    <br/><br/>
</form>

<button onclick="javascript:postGetPatientsForm();">Connect to Server</button>
Jan
źródło
1

Używając tego fragmentu, możesz przesłać formularz i uniknąć przekierowań. Zamiast tego możesz przekazać funkcję sukcesu jako argument i robić, co chcesz.

function submitForm(form, successFn){
    if (form.getAttribute("id") != '' || form.getAttribute("id") != null){
        var id = form.getAttribute("id");
    } else {
        console.log("Form id attribute was not set; the form cannot be serialized");
    }

    $.ajax({
        type: form.method,
        url: form.action,
        data: $(id).serializeArray(),
        dataType: "json",
        success: successFn,
        //error: errorFn(data)
    });
}

A potem po prostu zrób:

var formElement = document.getElementById("yourForm");
submitForm(formElement, function() {
    console.log("Form submitted");
});
jmojico
źródło
0

Jeśli kontrolujesz zaplecze, użyj czegoś takiego jak response.redirectzamiast response.send.

Możesz w tym celu utworzyć niestandardowe strony HTML lub po prostu przekierować do czegoś, co już masz.

W Express.js:

const handler = (req, res) => {
  const { body } = req
  handleResponse(body)
  .then(data => {
    console.log(data)
    res.redirect('https://yoursite.com/ok.html')
  })
  .catch(err => {
    console.log(err)
    res.redirect('https://yoursite.com/err.html')
  })
}
...
app.post('/endpoint', handler)
etw3
źródło