Rails: unexpected behaviour in Chrome and Firefox when refreshing invalid form page #229
Comments
I'm having the same problem. Have read https://github.com/turbolinks/turbolinks#redirecting-after-a-form-submission but not sure what to do. |
Same problem here |
Looks like a dupe of #60, which should be reopened. |
Just commented on #60 :) |
similar to #251 with test application to reproduce |
Is there any progress with this? |
Closing as duplicate of #60. I have added some more detail explaining the complexity in #60 (comment) |
@domchristie what you commented is for XHR (ajax). The issue still remains for non XHR. And I don't think this is a browser issue. For non XHR, when you submit a standard rails form to the "create" action and it fails validation, it changes the URL to that action (e.g. /articles (with method: POST)) as expected. Refreshing the page should call POST on /articles to resubmit the form instead of calling GET on /articles which goes to the index. |
@chase439 thanks for the clarification. This is caused by the call to Lines 97 to 101 in b85b343
To demonstrate that this is the cause, remove Turbolinks, run the following on every page load, then try and resubmit a form as before. history.replaceState({}, "", location.toString()) Given the differences between Safari and Chrome/Firefox, I wonder what the "correct" behaviour should be? It seems like calling I'm not sure if there is a solution to this, but reopening 😞 |
This doesn't retain the method type (e.g. POST). We need a different function that retains the method type or rethink the approach completely. Do we need to "prime the History API location with an initial restoration ID"? Should we let the browser primes the History API for us instead? |
There isn't one. The history interface defines the update steps for history entries to specifically require that, on replacement, "it represents a GET request, if it currently represents a non-GET request (e.g. it was the result of a POST submission)". No doubt a safety and security measure. The only standards-based way to retain a POST in the session history is to not disturb an existing entry. |
@inopinatus thanks for this. So whilst Safari behaves as we want, it is actually incorrect according to the spec :/
When Priming the History API location with Lines 45 to 54 in b85b343
History instance and utilise the null event.state when navigating back to an initial page. The revised popstate handler might look something like:
onPopState = (event: PopStateEvent) => {
if (this.shouldHandlePopState()) {
const location = Location.currentLocation
const restorationIdentifier = event.state ?
this.restorationIdentifierFromState(event.state) :
this.initialRestorationIdentifier()
if (restorationIdentifier) {
this.delegate.historyPoppedToLocationWithRestorationIdentifier(location, restorationIdentifier)
}
}
} |
Original posted on SO:
"When a user refreshes the page after submitting an invalid form, the browser should attempt to resubmit the form. In Chrome and Firefox (but not Safari) the browser performs a GET request on the create/update url instead.
The browser should resubmit the form (usually asking "Page reare you sure?" or similar), and render the same form-with-errors page. In Chrome and Firefox (but not Safari), on page refresh the browser sends a GET request to the POST url, effectively calling index.
f the url is not RESTful, or if you just happen to have no index or show views, reloading causes the app to throw a "No route" error."
This will lead a bad experience for user who try to fix their input on the form by pressing refresh button.
Such behavior only happen on Turbolink 5 , when the application using TL 2.5.3 it behave as expected.
The text was updated successfully, but these errors were encountered: