How to prevent history.pushState() and HTTP POST form causing a repost on a page refresh?
Asked Answered
S

3

7

I am currently facing a little problem with HTTP post forms and history pushstate.

When my user submits a POST form in example.com/page-1 and then clicks on a link within this page, they are redirected to example.com/page-2 with a history.pushstate. The JS script just changes the current url, pushes the old to the history, and then displays the new content. This works perfectly fine for me.

The problem: Once the user is on example.com/page-2 and manually refreshes the page (ctrl+r or refresh button), Chromes prompts the user to submit the form again; but the form was actually in example.com/page-1 and there is no reason to asked it again in this "new" page.

Is there a way to clear all the previously-submitted data in javascript on the popstate change to prevent repost prompt from the browser? Or am I missing something with my history states? Or is it something currently not implemented by the browser well yet?

I only tested it with chrome since I don't implement pushstate with other browsers.

Spectre answered 30/11, 2012 at 16:58 Comment(0)
F
2

Maybe try replaceState instead? See this.

The replaceState() method

history.replaceState() operates exactly like history.pushState() except that replaceState() modifies the current history entry instead of creating a new one.

replaceState() is particularly useful when you want to update the state object or URL of the current history entry in response to some user action.

Floc answered 14/12, 2012 at 21:33 Comment(1)
Hi, I got the same issue with replaceState, but I now send my forms via Ajax wich solves the problem. I guess that using javascript history.pushstate and replacestate without sending forms via ajax is not a good thing to do since its pretty easy to do so with jquery,mootools etc.Spectre
W
1

I have an identical issue - I'm using the History API with BackboneJS.

The solution that I have thought of is to have an intermediate page which the form redirects to after signing in. The purpose of this intermediate page is to add a non-POST page before the destination page so that the browser will not prompt to re-submit the form (and for Chrome to NOT add a redundant entry).

For your example, after submitting the POST form in example.com/page-1 the server should redirect the user to example.com/page-1a

example.com/page-1a can verify that the user credentials are present, and then redirect to example.com/page-2. This will solve your problem, I believe.

For the redirection mechanism, there are 3 options that I can think of:

  1. server-side redirect
  2. JavaScript (location.href="page-2")
  3. HTML header (<meta http-equiv="refresh" content="0; URL='http://example.com/page-2'" />)

Personally I have tried options 1 and 2 - they work fine for me. Hope this helps!

Wilkie answered 19/9, 2017 at 3:44 Comment(1)
This is known as POST-REDIRECT-GET (PRG for short), and is a common technique for avoiding these kinds of issues, such as re-POSTing on reload. This should work.Stylograph
P
1

After a POST is received you can redirect the user with a 303 See Other HTTP response which changes the request method to GET. Pressing reload after a 303 redirect will result in another GET request and users won't get prompted to submit the form again. I believe that is exactly what this status code is intended for.

The HyperText Transfer Protocol (HTTP) 303 See Other redirect status response code indicates that the redirects don't link to the requested resource itself, but to another page (such as a confirmation page, a representation of a real-world object — see HTTP range-14 — or an upload-progress page). This response code is often sent back as a result of PUT or POST. The method used to display this redirected page is always GET.

Pronation answered 11/10, 2023 at 23:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.