When my page does a post, I store all the $_POST
data in a separate $_SESSION
var. I know that a back button to this same page is by design to show the Document Expired
message. My hope is to fool the browser into thinking that there was really never any $_POST
data and so not to display the Document Expired
message when coming back to it. I am forcing a complete refresh of the page so I am not worried about receiving old data, since I have it stored in the session.
I have tried to unset($_POST)
hoping this will stay with the page. but the $_POST
data must be cached / stored and returns with a refresh or back button. Is what I am trying to do possible? Any ideas?
* UPDATE *
My solution / answer is posted below. It posts to a separate form, which redirects back to the original form for processing. Not sure why the down vote. It has been working great for months and I no longer receive Document Expired messages. It also prevents duplicate posting.
You can achieve this using the post - redirect - get design pattern.
http://en.wikipedia.org/wiki/Post/Redirect/Get
A more standard way to implement this pattern is to display, validate and save the form on one page.
The following solution has these advantages :
1. All form related code is in one place.
2. Server side validation is simple
I have two pages, form.php and after.php.
form.php :
if(isPosted()){
if(dataIsValid($postedData)){
// dataIsValid should set $message to show to the user
saveData($postedData);
redirect('after.php');
die();
}
} else {
$postedData = $defaultValues;
}
showForm($postedData, $message);
You can add the following to the beginning of your script to solve this issue.
header("Cache-Control: max-age=300, must-revalidate");
Simplest solution that comes to mind? Don't directly do the post, catch the event and submit the form through AJAX. Then on success, redirect.
An example using jQuery:
$('#some_form').submit(function() {
$.post($(this).attr('action'), $(this).serialize(), function() {
window.location = "/some/success/url.php";
});
return false; // Prevent the form submission & any other events triggered on submit
});
Because the POST never got added to the browser history, you won't have that issue.
However, note that the POST url is now different than the one you load; you can make it the same by checking whether a POST or a GET was done server-side, but either way, you have to do a bit of extra work to "remember" the results of the POST.
* UPDATE *
Here's my solution.
I am aware that with post-redirect-get the POST is usually back to the same page for processing before being redirected away from the form with a GET to another destination. However, I need to be able to return to the original page for re-editing (as in a document model where the user can SAVE work in progress). Therefore doing the POST to a second page and redirecting back to the original was my idea of getting rid of the "EXPIRED" message since the editing form would not have post data associated with it. I have extended this (not shown) to include $_FILE and other situations (e.g. using it with a href
as well). Not sure why the downvote. This has been working great for months now and accomplishes the task. I no longer receive "Document Expired" messages. In addition, all $_POST processing is accomplished in the original file.
testform.php
<?php
session_start();
if (isset($_GET) && count($_GET)>0){
// process get
var_dump($_GET);
}
if (isset($_SESSION['post-copy'])){
// return post vars to $_POST variable so can process as normal
$_POST = $_SESSION['post-copy'];
// unset the session var - with refresh can't double process
unset($_SESSION['post-copy']);
// process post vars
var_dump($_POST);
}
?>
<form method='post' action='__b.php?redirect=<?php echo $_SERVER['PHP_SELF'] ?>&help=me' enctype='multipart/form-data'>
<textarea name='descr' id='descr'>ABCD</textarea>
<input type='submit' value='Go'>
</form>
redirect.php
<?php
if (!isset($_SESSION)){
session_start();
}
if (isset($_POST)){
$_SESSION['post-copy'] = $_POST;
}
// retrieve the url to return to
if (isset($_GET['redirect'])){
$url = $_GET['redirect'];
}
// if multiple query string parameters passed in get, isolate the redirect so can build querystring with the rest
if (isset($_GET) && count($_GET) > 1){
$get = $_GET;
foreach ($get as $key => $val){
if ($key == 'redirect'){
// remove from rest of passed get query string
unset($get[$key]);
}
}
if (count($get) > 0){
$url .= (strpos($url,"?")===false ? "?" : "&") . http_build_query($get);
}
}
if ($url!==""){
header("Location: " . $url);
}
?>