When working with forms, we have to think about what will happen when someone clicks back or forward or refresh. For example, if you submit a form and right afterwards refresh the page, the browser will ask if you want to resend the data (usually in a pretty long alert box talking about making purchases).
People don't always read alert boxes, and often get used to clicking OK all the time (I know I fall in this category), so sometimes comments and other things get submitted more than once.
To solve this, you can simply do an HTTP redirect after processing the POST data. This is possible with any server-side language, but in PHP it would look something like this:
if (count($_POST)) {
// process the POST data
add_comment($_POST);
// redirect to the same page without the POST data
header("Location: ".$_SERVER['PHP_SELF']);
die;
}
This example assumes that you process the form data on the same page that you actually want to go to after submitting. You could just as easily redirect to a second landing page.
On this site, on each blog post page, I have a form that submits to the same blog post page. After processing the comment, I send a redirect again to the same page. If you add a comment and then refresh, or click back and then forward, the comment won't be submitted twice. (However, if you click back and then click Add Comment again, it will. I really should filter out duplicates, but that's another topic.)
This works because you essentially replace a POST request with a GET request. Your browser knows that POST requests are not supposed to be cached, and that you should be warned before repeating a POST request. After the redirect, the page is the result of a simple GET request. Refreshing the page simply reloads the GET request, leaving the POST request lost between the pages in your browser history.
wonderful. i have been doing self-redirect after post for along time and i can say that this is the single most important use of redirect!! thank you for your clear explanation! im sure it will help many
The only problem with this technique is that if you are using a CMS/blog that has to preload all it's code before a template is displayed, you essentially are causing twice the load because you are loading it twice (once for processing the post data, then the second time when you externally redirect back to itself).
Multiply this by a hundred people doing it at once on a busy site and your server will feel it.
I've am digging into the problem and it occurs to me there might be a way to clear post data on the client-side via javascript. Would cause zero extra server load. More research needed!
nice explanation. but this is what i get when i use this. ive been getting it before and i thought this would be a solution. it didnt solve it though. please let me knw how u can do that.
many thanx in advance:
Warning: Cannot modify header information - headers already sent by (output started at some-url-page.php:10) in myfilename.php on line XX
@nash - Sounds like the problem is some HTML or text has been outputted before you do header("Location") - and I bet that happened on line 10 of some-url-page.php.
Just make sure the header() function is called before anything gets outputted.
I want to use this method, and I know I've successfully used it in the past. But the problem I'm having now happens after the POST data is handled -- when the "Location: " header is sent, Firefox prompts me about whether I want to re-send my post data to the GET destination (which I don't of course - that's the problem I'm trying to avoid!) and the page goes blank if I answer 'No'. This is not a problem in IE. Any ideas?
My POST operation has the action "/home" and my redirect looks like "/home/eID/[some_id]". Thanks in advance!
i want redirct page to itself when some one change to and add process to this page
this is of course begging for a test ;-)
But seriously, I was thinking about using GWT just to avoid this (major) problem of postdata.
and this solution seems much better, thanks!
(It apparently doesn't stop you from pressing the submit button to early though)
Hi,I have doubt in jsp..i need to redirect the same page after inserting the data in to database....can u help me....Before that it ll be d inserted successfully,no need dis type of method.....
@vicky - I'm not that familiar with JSP, but a quick Google search for 'jsp redirect' gives the following example:
String redirectURL = "http://hostname.com/";
response.sendRedirect(redirectURL);
So you'd replace the redirectURL with the URL of the page. I hope that helps!
Great solution of this annoying problem! Thank you.
Hi jesse...i had one doubt...In(JSP & HTML) List out box,four options r there,i used option tag for select dat but its inserting in d database.....But mine doubt is, i have to select Multi more option in dat List out box,I donno wat option s dat...Can u clarify mine doubt(JSP)
Although this didn't directly help me solving my "Clearing post data when back to the original page", it helped me to device a method to solve the problem.
Thank you very much for your valuable teachings.
@ck : Assuming you aren't parsing scores of variables, you could pass along the same information as GET variables to be interpreted by the destination.
In example, a blog comment form:
if (count($_POST)) {
// process the POST data
add_comment($_POST);
// Collect and pass through variables
$subject=$_POST["subject"];
$name=$_POST["name"];
$url_append="?subj=$subject&name=$name";
// redirect to the same page without the POST data but with the variables
header("Location: ".$_SERVER['PHP_SELF'].$url_append);
die;
}
if ($_GET["subj"] && $_GET["name"]) {
// Read in the variables we passed via the URL
$subj=$_GET["subj"];
$name=$_GET["name"];
// Notify the user of action
echo "Thank you, $name. Your comment ($subj) has been recorded.";
}
An afterthought: You could set cookies for bulkier or session variables for sensitive data to be interpreted at the destination page. Yes it would increase server load some, but wouldn't require duplicate database queries... and cookies would incur little to no extra server load other than parsing variables.