-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to handle reloading pages created with POST #6600
Comments
This is great, thanks @jakearchibald! I think
That text should probably be limited to UI-initiated reloads. I think a nested error document inviting a full-page refresh is fine as a) it's UI and b) nested documents are an implementation detail users shouldn't have to understand. |
As to how to specify it, I think we only need a "she request body" member that is null or a byte sequence. |
Yeah, that's fair. The message doesn't suggest it will resubmit data, so it's fine.
Ah, yes. I messed that up in my "how to spec it" in a number of ways. The data we've got:
We can't use
If body is null, then the request is GET, otherwise it's POST. An empty list could be used for POST requests without a body. |
I was going to say that sounds good, but then I realized that would mean you'd have to run https://html.spec.whatwg.org/#submit-body before passing it to navigate. And then I realized that we probably want the multipart/form-data boundary string to stay consistent. Although maybe we don't care? |
Two options: Store the body as an abstract key/value format, similar to
Store the body as a byte sequence:
I'm not sure what's best. Maybe the latter, but with a note saying UAs can optimise by gathering the data from multiple places on demand, as long as the result is the same. And if that isn't possible (due to drive unexpectedly disconnected) then… network error? |
With @andreubotella's work in https://github.com/andreubotella/multipart-form-data we can actually store the boundary, which might well be what implementations do. So the latter is probably best (including the note and network error idea) and we can refactor later? |
In case anyone starts questioning their sanity, like I have been, Chrome does not show a prompt if devtools is open. https://bugs.chromium.org/p/chromium/issues/detail?id=1201204 |
Another test: Refreshing a page submitted with POST, after
|
The less user-facing prompts the better, so I wouldn't worry about it. (I suspect it's because |
I noodled on this a bit in #6315. A session history entry has a document state (which is shared between history entries that should share the same document), which has a resource which is a null, a srcdoc resource, or a POST resource.
|
I found an interesting HTML comment in the source:
|
Closes #6556. In particular, reverts document.open() to only update the document's URL, and not the session history entry's URL, like it did before ae7cf0c. Now that they can mismatch, we need to audit the cases where this might be important, which leads to the following changes: * Changes location.reload() to reload the current session history entry's URL, instead of the document's URL. This ensures that post-document.open() reload behavior is aligned with WebKit and Gecko, as tested by https://wpt.fyi/results/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/reload.window.html. * Changes history.pushState()/history.replaceState() with no URL argument to default to the document's URL, instead of the current session history's URL. This ensures that post-document.open() pushState()/replaceState() behavior is aligned with all engines, as tested by web-platform-tests/wpt#28826. This also modernizes and makes a bit more precise the location.reload() method steps. The user-initiated reload steps remain vague; #6600 will tackle those.
Hah, I wonder when that changed |
This came up as part of #6315, but it's previously been discussed:
I've been testing a few cases here:
Refreshing a page submitted with POST
Chrome, Firefox, Safari: Shows a prompt. Navigate unless prompt cancelled.
location.reload()
on a page submitted with POSTChrome: No prompt, just resends POST.
Firefox: Shows a prompt. Navigate unless prompt cancelled.
Safari: Reloads as GET.
This came up in #3215. The current spec seems to support what Safari is currently doing, but the current spec doesn't really cover this stuff properly.
Showing a prompt might be weird, especially if it appears out of nowhere.
Safari's behavior seems safest, especially as the caller of
location.reload()
doesn't know if the reload will be POST or not.Refreshing a page submitted with POST, after hash change
Chrome, Firefox, Safari: Shows a prompt. Navigate unless prompt cancelled.
Refreshing a page submitted with POST, after
pushState
changes URLChrome, Firefox: Navigates to new URL using GET.
Safari: Shows prompt. Unless cancelled, navigates to new URL using POST.
Safari's behavior of sending the POST data to a different URL is almost certainly wrong. Unless anyone disagrees, I'll spec what Firefox & Chrome do.
Traversing to top-level page previously sent with POST
Chrome, Firefox: Navigation takes you an 'error' page of sorts that invites you to refresh the page. Refreshing shows a prompt.
Safari: Prompt is shown when forward is pressed. Cancelling this prompt abandons the traversal.
Either of these seems ok, but I prefer the Chrome/Firefox behavior, and it's the one I'd like to spec. What Safari does here has complications when it comes to iframes, and the Chrome/Firefox behavior feels more consistent.
Traversing history in a way that navigates two iframes to pages previously sent with POST
Chrome: Iframes show a 'sad tab' icon, and nothing else.
Firefox: Iframes show a 'error' page of sorts that invites you to refresh the page. Clicking this button refreshes the top-level, not the iframe.
Safari: Shows a prompt. If the prompt is cancelled, the traversal is cancelled. If the prompt is accepted, only one of the iframes navigates.
The Safari behavior is broken here. The way refresh works in Firefox seems a bit weird. Although the error Chrome shows is vague, it seems best.
Traversing back to a page that contains two iframes previously sent with POST
Chrome, Firefox: As above.
Safari: Iframes fail to load.
In this case, the Safari behavior seems closer to Chrome/Firefox.
What to spec
Manually refreshing a page where the top-level was submitted via POST should show a prompt. I'm not sure about
location.reload()
. I think it should either downgrade to GET, or show a prompt.Using
pushState
means reloads of that document will be GET, even if thepushState
doesn't change the URL, or only the hash of the URL changes.Changing the hash of the URL by other means doesn't change anything in terms of refreshes. Refreshes will still show a prompt and use POST.
Traversing to a page previously fetched with POST will show an error page. If it's top-level, the error page can invite the user to refresh, which will prompt and re-POST. If it's nested, the error is not recoverable.
How to spec it
#6600 (comment)
The text was updated successfully, but these errors were encountered: