Hello to all! I am writing my simple function to send data from a form without reloading the page, but a problem has arisen: after sending the data via XMLHttpRequest, the page still reloads (sends the form with a get request). In this case, the server receives the data from the form, processes it and issues the appropriate response.

The form:

<form id="reg-form" onsubmit="sendForm(this.id, 'handler-url')> <input type="text" name="data"> <button>Send</button> 

Handler:

 var sendForm = function (formId, url) { 'use strict'; var form = document.getElementById(formId); var formData = new FormData(form); var xhr = new XMLHttpRequest(); // При установке этого заголовка работа функции прекращается ошибкой // xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhr.open("POST", url, true); xhr.send(formData); if (xhr.status == 200) { alert("Worked!"); } else { alert(xhr.status + ': ' + xhr.statusText+ 'Error'); } } 

The server responds with "OK", or if the sent data is entered incorrectly, sends json with a description of the errors. But in any case, I receive in the alert: "0: Error" and after that the form is sent get-ohm.

Please help me: how to make sure that the form is not sent get-ohm after XHR, and why can not I get a response from the server 200, although it sends it?

    4 answers 4

    1 return false; inside the submit handler implies stopping the form submission.

     var sendForm = function (formId, url) { 'use strict'; // ... ваш код return false;// добавить } 

    But since you have an inline onsubmit="return sendForm(this.id, 'handler-url');" , you need to put onsubmit="return sendForm(this.id, 'handler-url');" or onsubmit="sendForm(this.id, 'handler-url'); return false;"

    2 You need to check whether the response is ready (sending the request takes some time) at least so while (xhr.readyState != 4); And better to do this:

     xhr.onreadystatechange= function(){ if (xhr.readyState == 4) { if (xhr.status == 200) { // .... }; } } 
    • when the inline handler returns return false from sendForm is not enough, you need to return false from the inline Handler itself - Grundy
    • Yes @Grundy, false with inline is not transmitted. - nick_n_a

    The handler should be like this:

     <form id="reg-form" onsubmit="sendForm(this.id, 'handler-url');event.preventDefault();"> 

    Otherwise, the submit goes through the built-in script after the handler is executed.

    • Thanks, it really prevents the form from being sent after the handler is executed. - Roman Arsenyev
    • It remains to find out why xhr.status always returns 0, and not the real server response code. - Roman Arsenyev
    • @ Roman Arsenyev and this is because ajax is processed asynchronously. Synchronous processing seems to be possible, but it is customary to do this asynchronously. See onreadystatechange - developer.mozilla.org/en/docs/XMLHttpRequest . - Goncharov Alexander
    • @ Roman Arsenyev, I understand, everything is very simple - the third parameter .open should be false. false for synchronous, true for asynchronous. - Goncharov Alexander
    • one
      @GoncharovAleksandr, synchronous in some browsers may be marked as deprecated or deleted - Grundy

    Because the standard event of the submit event is

    To prevent it, you must either return false in the inline handler.

     <form id="reg-form" onsubmit="return sendForm(this.id, 'handler-url')> 
     var sendForm = function (formId, url) { 'use strict'; ... return false; } 

    Or call preventDefault

     <form id="reg-form" onsubmit="sendForm(event, this.id, 'handler-url')> 
     var sendForm = function (e, formId, url) { 'use strict'; e.preventDefault(); ... return false; } 

    Or use addEventListener instead of inline handler

     <form id="reg-form"> 
     document.getElementById('reg-form').addEventListener('click',function(){ sendForm(this.id, 'handler-url'); return false; }) function sendForm(formId, url) { 'use strict'; ... return false; } 

    or so

     <form id="reg-form"> 
     document.getElementById('reg-form').addEventListener('click',function(e){ e.preventDefault(); sendForm(this.id, 'handler-url'); }) function sendForm(formId, url) { 'use strict'; ... } 

      Thank you all for participating, based on your answers, I “collected” a more optimal (all the same, asynchrony is more optimal) and a more universal (inline-processor) method of form submission. The handler itself is of course not yet universal, for example, you need to add support for IE to it, but the initial problem is solved:

      The form:

       <form id="reg-form" onsubmit="sendForm(this.id, 'handler-url'); event.preventDefault();> <input type="text" name="data"> <button>Send</button> 

      Handler:

       var sendForm = function (formId, url) { 'use strict'; var form = document.getElementById(formId); var formData = new FormData(form); var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.send(formData); xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { alert("Worked!"); } else { alert(xhr.status + ': ' + xhr.statusText + 'Error'); } } }; } 
      • @Igor what nafig global event, you angered expert)) - Goncharov Alexander
      • @GoncharovAleksandr - for sure, thanks - Igor