2

I have a simple php form that submits (POSTS) data on pressing the SUBMIT button and a 'thank you' page is displayed and the data is stored in a database.

Usually on this thank you page if you press the BACK button on the browser and then the FORWARD button on the browser you are brought back to the same thank you page but the form is not submitted again.

In the last few days when I do the BACK and FORWARD on the browser the form resubmits the data and there's a duplicate entry in the database. This happens only in Chrome.

Have I made some errors in the settings in Chrome or is there some other problem somewhere?

  • are you using $_GET form the form inputs? then it would make sense: you're visiting the script with the form inputs in the url, thus it creates duplicates – kennypu Sep 07 '13 at 03:18
  • possible duplicate of [How to prevent buttons from submitting forms](http://stackoverflow.com/questions/932653/how-to-prevent-buttons-from-submitting-forms) – Vineet1982 Sep 07 '13 at 03:18
  • @Vineet1982: That question is about preventing buttons on the web page from submitting forms. This question is about preventing browser history navigation buttons from submitting forms. Answers from one are not applicable in the other. – icktoofay Sep 07 '13 at 03:29
  • @icktoofay both the things are similar as preventing buttons on web page from submitting form whether it is on web page or history navigation button. Button event is the same which is triggered. – Vineet1982 Sep 07 '13 at 03:32
  • @Vineet1982: How could that be? It's not like you can get a DOM reference to the history navigation buttons; how would you attach an event listener to it? The methods are clearly different. – icktoofay Sep 07 '13 at 03:34

4 Answers4

2

The typical solution is known as POST–Redirect–GET. Essentially, your form posts to a page which inserts the data into the database or whatever other actions are necessary and then redirects to another page. That other page doesn't actually do anything but just displays a success message or something. This way, you have two entries in the history: the form and the success page. The form-posting page is never added to the history; pressing back or forward will skip the submission.

icktoofay
  • 126,289
  • 21
  • 250
  • 231
  • 1
    Thanks! This solution will definitely work. But what's bothering is that this is only happening on CHROME and just recently. On the other browsers the back or forward button on the browser does not actually POST anything to the server - which I believe would be the default behavior of a browser?. – user2756166 Sep 08 '13 at 02:42
  • @user2756166: It does seem like undesirable behavior; I don't know why Chrome is doing that (and I don't think it does it for me, although I haven't thoroughly checked). I know that most browsers will try to keep old pages in memory, and if it's not accessed for a while and purged, the browser will reload it. I believe if it was reached through a `POST` some browsers will prompt you to make sure you want to re-`POST` it before actually doing that, but it appears that for you Chrome goes and does it without even prompting, which is strange. – icktoofay Sep 08 '13 at 03:56
1

Generate a value and put that inside a hidden field. If the user submits the form store that value (must be unique). If one tries to submit the form again with the same generated value, then do not execute your insert or update.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
0

You could set a cookie or session that says the form has already been submitted, and, if that is set don't resubmit the form, but that is basically a band-aid and may not even work...

What you should REALLY be doing is avoiding duplicates by checking the input values against existing values in the db, such as email or username. You should also set your email and username fields to UNIQUE in your database so you'll never get duplicate email addresses or usernames - solving your problem.

<?php
if($_SERVER['REQUEST_METHOD'] == 'POST')) {

    // 1. check if $_POST['email'] already exists in the database

    // 2. if email doesn't exist, insert data
}
timgavin
  • 4,972
  • 4
  • 36
  • 48
  • What if duplicates are valid but you don't want them to be added inadvertently? – icktoofay Sep 07 '13 at 03:37
  • How are duplicate usernames or email addresses valid? I guess that would be up the the logic of your app... Regardless, the OP was complaining of duplicates in his database, which this addresses. :) – timgavin Sep 07 '13 at 03:43
  • The OP never said they were dealing with usernames or email addresses. Inadvertent duplicates can be a problem whether they're valid or not. – icktoofay Sep 07 '13 at 03:45
  • Right, so you'd have to address that in your app. It depends on what you consider to be an acceptable duplicate. I was giving advice on how to ward off duplicates - he can apply that in any way he wants. – timgavin Sep 07 '13 at 03:48
  • Okay. I don't think it addresses the actual question of “How to prevent browser's forward button on Chrome from submitting a form?” but rather the question “How do I reduce damage from Chrome resubmitting a form (which I don't want it to be doing anyway)?” – icktoofay Sep 07 '13 at 03:49
-2

Th issue is, when you reached the success page and refreshed, the browser has to resubmit the cached data; because the page where it reached is dynamically generated. Now when you click on the okay, the data which was previously stored in the $_POST variable is resubmitted. To stop it, you would have use dynamic binding instead of static binding.

A simple solution to this issue is:

  1. Make the action attribute of the form blank i.e <form action="">.
  2. Call a javascript method onclick of the intended button.
  3. Add the Action attribute in the JS method and submit the form.
Srihari
  • 766
  • 1
  • 6
  • 22
  • How would setting the `action` dynamically help? The browser stores the history separately; it's not like it consults the `action` of the form used to navigate to a page when pressing forward. – icktoofay Sep 07 '13 at 03:35
  • The browser stores the history, but doesn't know where to submit. The action URL was blank, as the browser remembers it. Only the javascript function that bound the URL knows what URL to post. You can try it. – Srihari Sep 07 '13 at 03:37
  • “The action URL was blank, as the browser remembers it” is false. The browser remembers wherever it actually went; it cares not about what was originally in the HTML. To demonstrate that, I made [this little fiddle](http://fiddle.jshell.net/fj98f/show/). Observe that the HTML has an empty `action` and that `action` is set by JavaScript. If you use one of the “set action” links, press submit, go back, press the other “set action” link and go forward *without pressing submit again*, you'll note that the browser ***did not*** reconsult the `action`. – icktoofay Sep 07 '13 at 03:46
  • Seem to have misunderstood the question which is regarding History navigation causing form resubmission – Jacques Oct 15 '15 at 13:59