Come inviare un modulo HTML senza reindirizzamento


95

Se ho un modulo come questo,

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

come posso inviarlo senza reindirizzare a un'altra vista tramite JavaScript / jQuery?

Ho letto molte risposte da Stack Overflow, ma tutte mi reindirizzano alla vista restituita dalla funzione POST.


Vuoi una richiesta XHR (AJAX)
Sterling Archer

2
XHR / AJAX è un modo: invia il post e ottiene la risposta dietro le quinte, quindi il browser non lascia mai la pagina in cui si trova. Un altro modo è un reindirizzamento lato server dopo l'elaborazione del messaggio, che dipende dalla tecnologia server che stai utilizzando.
Stephen P,

@StephenP Uso ASP.NET MVC 5.1.
Duke Nuke

@Duke, sto solo dicendo che c'è più di un approccio (ajax vs. server-redirect) e la tua scelta dipende dalle tue esigenze. I siti moderni molto probabilmente vorranno fare ajax. Nota anche che tutte queste risposte dicono che hai bisogno di jQuery - jQuery è fantastico ma ci sono , in effetti, altri modi per fare ajax ... anche se io stesso userei jQuery.
Stephen P

1
Il mio modo è semplice, pulito ed elegante, e sono solo 2 righe di codice. Non utilizza script e funziona in HTML4 e versioni successive, anche se JavaScript è disattivato.
Issa Chanzi

Risposte:


74

Per ottenere ciò che desideri, devi utilizzare jQuery Ajax come di seguito:

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

Prova anche questo:

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

Soluzione finale

Questo ha funzionato perfettamente. Chiamo questa funzione daHtml.ActionLink(...)

function SubForm (){
    $.ajax({
        url: '/Person/Edit/@Model.Id/',
        type: 'post',
        data: $('#myForm').serialize(),
        success: function(){
            alert("worked");
        }
    });
}

Ha funzionato alla grande, il problema è che non voglio che venga automaticamente (sempre) inviato in questo modo. Mi piacerebbe avere una funzione con un nome per fare queste cose che hai postato nella tua risposta. Quindi posso invocarlo manualmente quando voglio, per fargli pubblicare il modulo. Come sotto posso dare il nome della funzione da invocare. @Html.ActionLink("Add a Report", "Create", "Reports", new { carId = Model.Id }, new { onclick = "FUNCTION_WHICH_SUBMITES_FORM()" })
Duke Nuke

Ha funzionato:function SubForm (){ alert("1"); //e.preventDefault(); $.ajax({ url:'/Car/Edit/@Model.Id/', type:'post', data:$('#myForm').serialize(), success:function(){ alert("fasf"); } }); }
Duke Nuke,

Per qualche motivo la tua seconda soluzione non ha funzionato, ma quella che ho pubblicato nell'ultimo commento sì. Aggiungerò la mia soluzione al tuo post perché solo grazie a te potrei raggiungere questo obiettivo.
Duke Nuke,

1
anche il secondo deve funzionare, potrebbe esserci qualcos'altro, ma se hai trovato la soluzione non abbiamo bisogno di andare su quella strada adesso! felice che abbia aiutato;)
Amin Jafari

Grazie, questa risposta mi ha anche aiutato a inserire un testo personalizzato al posto del modulo dopo l'invio
Anupam

116

Puoi ottenerlo reindirizzando il modulo actiona un file invisibile <iframe>. Non richiede JavaScript o altri tipi di script.

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

<form action="submitscript.php" target="dummyframe">
    <!-- Form body here -->
</form>

1
Questo è fantastico. Ma come posso fare qualcosa, dopo aver inviato il modulo? cioè i campi di testo del form dovranno essere vuoti, il focus torna al primo campo, ecc.
Pranjal Choladhara

1
C'è un qualche tipo di javascript che può farlo. Basta cambiare <input type='submit'...in <input type='reset'e aggiungereonclick='document.forms["myForm"].submit();'>
Issa Chanzi

Bella risposta! Funziona alla grande
Cybrus

Fai attenzione, è probabile che ricarichi la pagina in cui si trova il tuo modulo nell'iframe, il che può causare problemi di prestazioni se stai creando un'app o un grande sito web.
Alexandre Daubricourt

22

Posiziona un nascosto iFramenella parte inferiore della pagina e targetnel modulo:

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

Facile e veloce. Tieni presente che, sebbene l' targetattributo sia ancora ampiamente supportato (e supportato in HTML5), è stato deprecato in HTML 4.01.

Quindi dovresti davvero usare Ajax per essere a prova di futuro.


Secondo MDN, questo comportamento per il targetè completamente valido, quindi AJAX è ancora opzionale.
Daniel De León

18

Poiché tutte le risposte attuali utilizzano jQuery o trucchi con iframe, ho pensato che non ci fosse alcun danno ad aggiungere un metodo con un semplice 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);
}

2
Grazie mille!
Joshua Evans,

Ti do il cappello. Ho passato ore cercando di capire come ottenere jquery per inviare un modulo a un backend nginx con il parametro contentType = false e ottenere sempre un 415 come risultato. Questa è stata l'unica soluzione che ho trovato che ha risolto il mio problema particolare.
user12066

7

Ok, non ti dirò un modo magico di farlo perché non c'è. Se hai un attributo di azione impostato per un elemento del modulo, verrà reindirizzato.

Se non vuoi che reindirizzi semplicemente non impostare alcuna azione e impostare onsubmit="someFunction();"

Nel tuo someFunction()fai quello che vuoi, (con AJAX o no) e alla fine, aggiungi return false;per dire al browser di non inviare il modulo ...


1
C'è un modo magico per farlo. Imposta un attributo di destinazione in modo che il modulo reindirizzi a un punto diverso dal frame corrente. Se aggiungi un iframe invisibile per cose come questa nelle tue pagine. È piuttosto semplice.
Issa Chanzi

5

Hai bisogno dell'Ajax per realizzarlo. Qualcosa come questo:

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

5
C'è qualche motivo particolare per cui non indenti questo codice sorgente? Sembra che il codice degli anni Sessanta prima dell'invenzione del C. Ho pensato che fossimo finiti per molto tempo.
Alfe

2

Vedi la postfunzione di jQuery .

Creerei un pulsante, imposterei una onClickListener( $('#button').on('click', function(){});) e invierei i dati nella funzione.

Inoltre, vedi la preventDefaultfunzione, di jQuery!


2

Soluzione one-liner a partire dal 2020, se i tuoi dati non devono essere inviati come multipart/form-datao application/x-www-form-urlencoded:

<form onsubmit='return false'>
    <!-- ... -->           
</form>

3
Se si combina questo con gli OP action="...", ciò impedisce efficacemente il cambio di pagina, ma impedisce anche che i dati vengano inviati attraverso la rete.
Kev

@Kev Invio personalmente i miei dati tramite JS XHR, ecco perché non voglio il reindirizzamento della pagina, perché è un'app JS
Alexandre Daubricourt

@Kev Scusa avrei dovuto menzionarlo
Alexandre Daubricourt

1

L'effetto desiderato può essere ottenuto anche spostando il pulsante di invio all'esterno del modulo come descritto qui:

Impedisci il ricaricamento della pagina e il reindirizzamento sul modulo submit ajax / jquery

Come questo:

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

1

Utilizzando questo snippet, puoi inviare il modulo ed evitare il reindirizzamento. Invece puoi passare la funzione di successo come argomento e fare quello che vuoi.

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

E poi fai:

var formElement = document.getElementById("yourForm");
submitForm(formElement, function() {
    console.log("Form submitted");
});

0

Se controlli il back-end, usa qualcosa come response.redirectinvece di response.send.

Puoi creare pagine HTML personalizzate per questo o semplicemente reindirizzare a qualcosa che hai già.

In 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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.