Discussion:
[whatwg] Adding progress event for native <form>?
Mikko Rantalainen
2017-04-11 12:44:39 UTC
Permalink
I see that https://xhr.spec.whatwg.org/ already defines ProgressEvent
for XMLHttpRequest.

Would it be possible to add "progress", "load", etc. events to normal
form elements, too? Basically, I would like to do

form.addEventListener('progress', function (e) {...})

and if the end user hits the Submit button, my progress listener would
get called with ProgressEvent with lengthComputable, loaded and total
attributes.

If I have understood correctly, this does not make any information
available to JavaScript that is not already available because JavaScript
*can* already evaluate all form fields, use FileReader API to get all
the files in file inputs and submit the form to the same action URL
using XMLHttpRequest. In addition, browsers already implement all the
required code because XMLHttpRequest needs that behavior.

If listening for "progress" were allowed, I could implement my own form
submission UI and still use regular forms that would work even without
JavaScript.
--
Mikko
Anne van Kesteren
2017-04-11 13:05:42 UTC
Permalink
On Tue, Apr 11, 2017 at 2:44 PM, Mikko Rantalainen
Post by Mikko Rantalainen
I see that https://xhr.spec.whatwg.org/ already defines ProgressEvent
for XMLHttpRequest.
Would it be possible to add "progress", "load", etc. events to normal
form elements, too? Basically, I would like to do
form.addEventListener('progress', function (e) {...})
and if the end user hits the Submit button, my progress listener would
get called with ProgressEvent with lengthComputable, loaded and total
attributes.
If I have understood correctly, this does not make any information
available to JavaScript that is not already available because JavaScript
*can* already evaluate all form fields, use FileReader API to get all
the files in file inputs and submit the form to the same action URL
using XMLHttpRequest. In addition, browsers already implement all the
required code because XMLHttpRequest needs that behavior.
If listening for "progress" were allowed, I could implement my own form
submission UI and still use regular forms that would work even without
JavaScript.
It would leak new information cross-origin and due to redirects that
would be hard to distinguish from same-origin. You'd also have to
submit into some kind of <iframe> as otherwise you end up navigating
anyway.
--
https://annevankesteren.nl/
Mikko Rantalainen
2017-04-12 07:16:26 UTC
Permalink
Post by Anne van Kesteren
On Tue, Apr 11, 2017 at 2:44 PM, Mikko Rantalainen
Post by Mikko Rantalainen
Would it be possible to add "progress", "load", etc. events to normal
form elements, too? Basically, I would like to do
form.addEventListener('progress', function (e) {...})
and if the end user hits the Submit button, my progress listener would
get called with ProgressEvent with lengthComputable, loaded and total
attributes.
[...]
If listening for "progress" were allowed, I could implement my own form
submission UI and still use regular forms that would work even without
JavaScript.
It would leak new information cross-origin and due to redirects that
would be hard to distinguish from same-origin. You'd also have to
submit into some kind of <iframe> as otherwise you end up navigating
anyway.
The default use case would not need to use frames. The expected use case
would be to display custom UI for submission progress (e.g. nice
progress bar and ETA with custom algorithm). It would be just fine to
"lose" this custom UI once the submission is complete and next page or
resource has been displayed.

About the information leak: in case of cross-origin the user agent could
emit just one progress event with lengthComputable=false. However, I
have throuble figuring out a possible attack vendor even in case full
progress events were published cross-origin.

I didn't understand the point about redirects making
same-origin/cross-origin harder to distinguish.
--
Mikko
Anne van Kesteren
2017-04-12 07:25:20 UTC
Permalink
On Wed, Apr 12, 2017 at 9:16 AM, Mikko Rantalainen
Post by Mikko Rantalainen
The default use case would not need to use frames. The expected use case
would be to display custom UI for submission progress (e.g. nice
progress bar and ETA with custom algorithm). It would be just fine to
"lose" this custom UI once the submission is complete and next page or
resource has been displayed.
Every now and then there's some talk about navigation transition
animations. That might be all you need here. (Sorry, no pointer at
hand.)
Post by Mikko Rantalainen
About the information leak: in case of cross-origin the user agent could
emit just one progress event with lengthComputable=false. However, I
have throuble figuring out a possible attack vendor even in case full
progress events were published cross-origin.
The problem is learning information about the destination server and
being able to do better timing attacks.
Post by Mikko Rantalainen
I didn't understand the point about redirects making
same-origin/cross-origin harder to distinguish.
Because at the point you'd hit such a redirect we'd have to stop
notifying you, but that would also reveal something if things are
still ongoing.
--
https://annevankesteren.nl/
Mikko Rantalainen
2017-04-13 09:22:50 UTC
Permalink
Post by Anne van Kesteren
On Wed, Apr 12, 2017 at 9:16 AM, Mikko Rantalainen
Post by Mikko Rantalainen
The default use case would not need to use frames. The expected use case
would be to display custom UI for submission progress (e.g. nice
progress bar and ETA with custom algorithm). It would be just fine to
"lose" this custom UI once the submission is complete and next page or
resource has been displayed.
Every now and then there's some talk about navigation transition
animations. That might be all you need here. (Sorry, no pointer at
hand.)
I don't agree that transition animations are enough.

Consider a mobile user uploading a form with 50 MB file over 2G EDGE
connection (about 250 Kbps in practice). Such form submission will take
around 25-30 minutes. End user will not be happy with native user agent
progress display (for example, Google Chrome will display only a small
status text in bottom left corner saying 'Uploading (3%)...').
Navigation transition cannot obviously hide the 25 minute delay required
for the upload.

I'd expect a good upload UI to look more like the displays used in
http://beta.speedtest.net/ during the network connection testing. User
agents have had 20+ years to improve on such UI without success so I'd
like to have JS API to have a possibility to implement the missing UI by
myself.

Currently the only way to do this is to add JS code that attaches to the
form, prevents normal form submission, collects all form data including
file uploads and then uses XHR to submit the data while listening for
'progress' events. That's pretty much work to do just to show client
side progress bar and that may still not work correctly if server
responds to POST request with HTTP 303 because XHR cannot read original
response headers nor response body in case of redirects. In case of HTTP
303 JavaScript code would need to read the Location header and set
document.location to that value instead of getting headers and content
after the redirect.

Another possibility is to forget about HTML forms and non-JavaScript
fallback and always go with XHR specific implementation.
Post by Anne van Kesteren
Post by Mikko Rantalainen
About the information leak: in case of cross-origin the user agent could
emit just one progress event with lengthComputable=false. However, I
have throuble figuring out a possible attack vendor even in case full
progress events were published cross-origin.
The problem is learning information about the destination server and
being able to do better timing attacks.
OK. I think it would be fine to not publish details via progress events
as described above (lengthComputable=false) in case cross-origin traffic
would be needed.
--
Mikko
Loading...