[whatwg] page refresh and resubmitting POST state

On Fri, May 22, 2009 at 4:48 PM, Mike Wilson <mikewse at hotmail.com> wrote:
> Thanks for expanding on my previous mail, Jonas, but I was assuming
> that everyone on this list was aware of the PRG pattern and its
> existing support in browsers.
>
> With current technology there are limitations to the usefulness of
> PRG (f ex in multi-window/tab scenarios), so I am asking if it is
> within HTML5's scope to explore improved or alternative solutions
> to the "resubmit" problem.

It's not safe to assume that the readers here are familiar with web
application design patterns.  A lot of readers are browser
implementers, not web developers, and in fact those are the most
important ones.  You should spell out the existing problem carefully
and in great detail, including existing solutions or workarounds, to
get the best response.  I've tried outlining it later in this post,
but you might be able to contribute further info.

A clear and complete list of features that a solution must have would
be best.  Take a look at this for an example of an appropriately
stated use-case:
http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2009-May/019668.html

On Fri, May 22, 2009 at 7:31 PM, Kornel Lesinski <kornel at geekhood.net> wrote:
> As far as I understand the "resubmit problem" is just sign of poor implementation that violates SHOULD NOT in the HTTP RFC:
> http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13
>
> This problem can be elegantly solved within existing standards: Opera simply goes back in history without resubmitting forms, and resubmits only when user clicks standard Reload button (or F5, etc.)

Firefox does that too, at least in 3.5b4pre.  But this solution only
works if the page is still in the browser's history cache.  Browsers
can't keep pages in their cache forever -- it fills up and needs to be
emptied.  They could be biased in favor of keeping POST results,
though.  If this could work consistently enough, I think it would
negate the problem.  I don't think refresh is a big deal.

On Sat, May 23, 2009 at 1:04 PM, Kornel Lesinski <kornel at geekhood.net> wrote:
> * If it's not safe to resubmit, use status 303. I know it's not very convenient, but can be implemented reasonably well and works with existing browsers.

The problem is that since HTTP is stateless, you don't have the data
available to show a confirmation page.  For instance, suppose a user
on Wikipedia moves a page to a new name.  That user is presented with
a page saying "You have successfully moved X to Y."  If this
confirmation page is the result of a POST, then trying to go back in
the history (in Firefox, at least) will risk presenting the annoying
"Do you want to resubmit?" dialog.  But if you use a 303 (practically,
302), then how do you know what X and Y are in the new request?

One workaround is to just stick the info in the query string of the
GET.  One problem with this is that it makes it easy to trick users
into thinking they've just done something alarming: you can link to
confirmmove.php?page1=Main_Page&page2=Main_Page_ON_WHEELS, and the
user will think they actually just moved the page (the software told
them so!).  Another problem is that sometimes there's way too much
data to fit into a query string.  For instance, in MediaWiki you can
move a page with all its subpages.  There might be hundreds or even
thousands of these, and a success/failure message is printed for each,
with the reason for failure if appropriate.  This might be too long to
fit in a GET.

Another workaround is to have a database table or memcached key or
something that stores a "move ID" with the info, and put the move ID
in the URL.  So the POST would set "818850324da69994" in the database
to correspond to the info "User X moved Y to Z", then redirect the
user to confirmmove.php?id=818850324da69994.  That would then look up
the ID in the database/memcached to display the confirmation info.   I
haven't done this myself, so I can't give detailed info on its
problems.  But it's clearly very cumbersome, and uglier for the user.

A similar workaround would be to use cookies.  This is nicer than the
previous method, but has the potential to break confusingly if the
user takes several similar actions at once (e.g., moving a number of
pages at once in multiple tabs).

Yet another workaround would be just to dispense with the confirmation
page.  For instance, when making a new post in a forum, the user could
just be taken to the new post instead of being given a page saying
"Post successful".  But in some cases, it's important to know the
result of the action taken.  Partial failures might need to be
reported (like 15 pages out of 300 failing in a mass move in
MediaWiki), or other outcomes that the action-taker can't predict in
advance.

I don't know of any other workarounds offhand.  I'm not sure what the
requirements for an ideal solution would be.  It seems to me that if
browsers just reliably kept POST results in their cache for long
enough, it would be a non-issue.  (In fact, MediaWiki mostly just
doesn't work around the problem at all, and shows confirmation pages
as POST responses.)

> * If it's safe to resubmit, use PUT method (allowed in HTML 5), which is idempotent by definition.

Theoretically, but not really in practice.  Someone else might have
PUT something new at the URL since your last PUT, or DELETEd it, or
otherwise done something to it.  In that case, you'd overwrite their
modifications.  PUT is only practically idempotent if only one user is
modifying the resource, as far as I can tell.

Received on Sunday, 24 May 2009 07:41:12 UTC