0

Does any browser support a JS API to query the status of submitting a form? I would like to add generic code to our application that monitors any submitted form and displays a progress bar for the form. Origin server cannot report the status if there's buffering reverse proxy between client and the origin server (e.g. Cloudflare) so I would need something supported by the client.

Assume that I run code document.getElementById("myForm").submit();. Is there any way to figure out how much of the form has been submitted? The client obviously knows the exact byte count it will be sending so it should be able to report how much (count of bytes or a percentage) of the full transfer has been pushed to net socket. I understand that this is not the same as getting the data to the origin server but I'm not interested on that. I would like to support long forms (lots of text over very slow internet connection) and forms with huge files (files bigger than 2 GB over fast internet connection).

Update: I asked about this on WHATWG mailing list. I believe the best answer this far is https://stackoverflow.com/a/28386477/334451 which does not deal great with HTTP 303 but should be otherwise okay.

Community
  • 1
  • 1
Mikko Rantalainen
  • 14,132
  • 10
  • 74
  • 112
  • Are you using AJAX or normal form submit ? – Shakti Phartiyal Apr 11 '17 at 06:17
  • Possible duplicate of [Displaying a progress bar showing the progress of a form submission](http://stackoverflow.com/questions/21902385/displaying-a-progress-bar-showing-the-progress-of-a-form-submission) – Arg0n Apr 11 '17 at 06:20
  • https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress – jeremiah.trein Apr 11 '17 at 06:21
  • @ShaktiPhartiyal I'd prefer normal form submit but still follow the progress. However, I'm willing to implement this with AJAX if that's the only way to make it work. – Mikko Rantalainen Apr 11 '17 at 11:27
  • @Arg0n: I don't think this is a duplicate because I'm trying to specifically send a native `
    ` element. I'd like to use JS only to improve the UI but be able to submit the form without server modifications. In practice, I'd need to be able to submit files, too. And correctly handle any possible HTTP 303 responses. I believe that Ajax/XHR does not handle the HTTP 303 very well.
    – Mikko Rantalainen Apr 18 '17 at 12:52

1 Answers1

0

There's no way to do this without using using AJAX/XHR via JavaScript and listening for progress events that way.

This will probably never be implemented for native form submission because it would allow more accurate timing measurements for response time side-channel attacks. See explanation by Anne van Kesteren for details.

Because AJAX/XHR cannot submit to cross-origin servers, it's okay to get accurate timing for those submissions. However, native forms can submit cross-origin and there even the timing for any possible redirects could leak information about the remote cross-origin server. As exposing the timing for native submission would leak more data than existing APIs, this will not be added to native submission API.

You can handle the existing form like this:

form = ... ; // the HTMLFormElement you want to monitor for submission

form.addEventListener('submit', function (e)
{
    let xhr = new XMLHttpRequest();
    xhr.upload.addEventListener('loadstart', function ..., { capture: false, passive: true });
    xhr.upload.addEventListener('progress', function ..., { capture: false, passive: true });
    xhr.addEventListener('readystatechange', function ..., { capture: false, passive: true });
    xhr.upload.addEventListener('error', function ..., { capture: false, passive: true });
    xhr.upload.addEventListener('abort', function ..., { capture: false, passive: true });
    xhr.upload.addEventListener('load', function ..., { capture: false, passive: true });
    xhr.addEventListener('readystatechange', function ..., { capture: false, passive: true });

    data = new FormData(form);
    // data.append(key, value); // if you want to add extra data
    xhr.send(formdata);

    e.preventDefault();
}

And yes, you need all those event listeners to be compatible with all the browsers and to handle all edge cases and to get all possible timing. And you'll have to create the UI to explain the user about failing network connection, timeouts, etc etc that the browser typically takes care of.

Mikko Rantalainen
  • 14,132
  • 10
  • 74
  • 112