How to avoid POSTDATA resend warning
how-to, php, tutorial January 12th, 2008"POSTDATA resend" warning is a common problem when developing web applications. Before discussing about the solution, let’s know what is the problem actually and when it arises.
About the problem :
We see this warning when we try to revisit a page that has accepted POSTDATA using browser’s history mechanism. Usually we do it by browser’s BACK button or refreshing a page. When a page in browser history requested with POST method, the browser thinks this POSTDATA is important to process this page. So, it asks the user if he wants to send the POSTDATA again or not. Different browsers show this warning differently. For example, the images below shows how Firefox and Internet Explorer show this warning.
|
POSTDATA resend warning in Mozilla Firefox |
|
POSTDATA resend warning in Internet Explorer |
Now, If the user accepts the confirmation, the page is reloaded with previously sent data using POST method; otherwise some browsers don’t take any action and some shows a "Webpage has expired" message. In some situations, this re-submitting is useful, but most of the times it’s not expected. It’s more harmful when user accepts it without understanding and causes multiple entries of previously entered data in database.
The easy solution :
The easy solution is simply redirecting. When we redirect a page, the target page is loaded without any POST data that comes with request.
Let’s solve this problem by hand. Say we have 2 pages - A and B. A has a feedback form which submits data by POST request method to B. B inserts the information into database and shows a success message.
Now, if the user try to reload the page by refresh, back button or any other way, browser will show the confirmation message. If user accepts this, the message will inserted again. But after inserting to database, If we redirect to another page C and C shows the success message, the problem will not occur. Because, in the final output to the browser will come from C which didn’t use any POST request data. The code should be something like this:
<?php
if($_POST)
{
/* Form validation, Inserting to database or anything you want goes here */
/* Now redirect to another page */
header('Location: http://yoursite.com/success.php');
}
?>
Extending the solution :
The solution I explained above can show just an static message like "Thanks for your feedback" or "Registration completed successfully" etc. But usually we like to include some information about sender or submitted information in the success of failure message. For example:
Hi Andrew, your registration is successfully completed. An email is sent to you at andy001@yahoo.com with more information.
In the above message, the purple colored information has to be taken from POST data. But the POST data will be lost when redirecting. So, it’s not possible by the above solution.
What we can do to solve this is that we can use SESSION to store those data which we want to display with message in redirected page. Just like this:
<?php
session_start();
if($_POST)
{
/* Form validatio, Inserting to database or anything you want goes here */
//Store data to session
$_SESSION['name'] = $_POST['name'];
$_SESSION['email'] = $_POST['email'];
//Now redirect to another page
header('Location: http://yoursite.com/success.php');
}
?>













January 13th, 2008 at 3:44 am
After assiging session varaibles you have to unset this variables in the success.php.
You’ve not quoted it.
Thanks.
January 13th, 2008 at 3:58 pm
I think this pattern is still new to a lot of web developers.
Wikipedia: http://en.wikipedia.org/wiki/Post/Redirect/Get
January 13th, 2008 at 4:48 pm
Simpler solution:
January 13th, 2008 at 10:09 pm
@Panucci & stojec: Thanks a lot.
@Jahedur Rahman: It’s depending on for which purpose the script is being used.
Sometimes you should unset it just after displaying a successmessage. But remember that, for the example used here, after u unset this values from session, the message will be shown without name and email address.
January 13th, 2008 at 11:40 pm
[...] Uddin Ahmad shared a tip on how to avoid POSTDATA resend warning from the [...]
January 14th, 2008 at 2:52 am
there is a component for Java web developers with Redirect after POST pattern: http://www.servletsuite.com/servlets/redirectafterpost.htm
January 14th, 2008 at 9:49 am
In this simplistic example you’ve prevented the POSTDATA warning. But the code under “extending the solution” introduces a bug.
What happens when the user refreshes the success page after the PHP session expires?
$_SESSION['name'] and $_SESSION['email'] will be unset!
This redirect method is safer:
//Now redirect to another page
header(‘Location: http://yoursite.com/success.php?name=blah=email=blah@hotmail.com’);
Of course ensure values are url-encoded
January 14th, 2008 at 12:38 pm
Hi Quinton,
Thanks for this solution. It’s really a lot easier. When I m sure that, no special character will occur in values, I also use this post/redirect/get technique.
For the current solution, when u will unset the session is depends on functionality of your script. If there is no specific reason, you shouldn’t unset the session values immediately. And for some situation, say if you redirect to current page, you have to unset it immediately after displaying and message and should check if the session is set before displaying message each time.
Thanks again for your comment.
January 17th, 2008 at 12:24 am
Nice effort
January 30th, 2008 at 10:18 pm
[...] this. Whether you use IE or Firefox (I assume other browsers as well) whenever you refreshed, the infamous resending postdata dialog would present itself to take care of you in case you were sending delicate information like a [...]
May 10th, 2008 at 6:27 pm
i keep on having POSTDATA when i refresh
May 19th, 2008 at 8:20 am
A really easy untech way to solve this problem is to start firefox in safe mode and check the box to delete add-ons. Somehow we had add-ons of Talkback and Skype, neither of which we put on. Once they were removed, no more Postdata message. I think the problem was caused by skype.
May 30th, 2008 at 9:52 am
Like oscar, I’ve used this pattern before and under some server setups, I continue to see POSTDATA messages even after the redirection. I’ve not confirmed that this is the case, but I think IIS and Apache work differently with respect to this pattern.
July 17th, 2008 at 8:15 am
Can any body guide me how i can use code(on which location i have to paste) to get rid of this problem.
thanks
July 23rd, 2008 at 9:32 am
how about doing this via javascript - refresh the current location minus post variables:
// or make variable & convert to string
refresh = parent.location;
// assign location as this string
parent.location = refresh;
July 24th, 2008 at 9:52 pm
Good
August 20th, 2008 at 4:29 pm
Thanks.
It help me very much
September 15th, 2008 at 5:21 pm
Ive use this in the past
try it out, but it only seems to work for IE and will break with a refresh
Can anyone make it work for firefox
September 15th, 2008 at 5:24 pm
I use this php
if ($_SERVER['REQUEST_METHOD']==’POST’)
{
header(’Expires: ‘ . gmdate(”D, d M Y H:i:s”, time()+1000) . ‘ GMT’);
header(’Cache-Control: Private’);
}
September 15th, 2008 at 5:50 pm
@datafake:
Thanks for commenting.
Here all the tasks are being done from php. So, how can it be different for IE and FF?
And, in your second comment, you’ve written a code snippet which have no effect on this technique.
Can u plz try this (either using my technique or as said in comment:7) once again for FF?
Thanks
September 23rd, 2008 at 5:37 pm
Hi, there.
What Ive suggested is an completely alternative solution I found that doesn’t involve a redirect. It isnt as complete a solution as yours but I think its relevant to the discussion.
If you POST some variables to a PHP page that has my snippet at the top.
Then go to a new page.
Then go back.
You will not get the resubmit POST warning in IE. You will just see the cached output that was generated.
If you then refresh you will get the resubmit warning.
Its my technique that doesnt work in firefox presumably because it must handle the headers differently.
Thanks