CodeIgniter Forums

Full Version: Preventing double post data being resent
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

El Forum

[eluser]worchyld[/eluser]
Typically when pressing submit on a form, and its sending POST data to itself, and you press F5, it'll bring up the message;

Quote:The page you are trying to view contains POSTDATA. If you resend the data, any action the form carried out (such as a search, or an online purchase) will be repeated.

In the past, I resolved this problem by doing this;

Quote:1. Make the form page go to a processing file (process-something.php)

2. The processing file will do whatever is needed, validation, SQL inputs, etc and then do a header redirect to step 1.

3. Pressing F5 after this does not produce the "POSTDATA" message.

How do you prevent the POSTDATA message/double posting on CI?

I thought you could do it by replicating the same procedure (ie: having a processing file act as a middleman) but the POSTDATA message still appears, also I have to repeat a lot of code over, otherwise it'll complain it's missing a page variable.

ie;
Code:
// This first controller just displays the form, it doesn't handle any processing.
// All processing is handled with a middleman to prevent double posting data being resent
// A majority of libraries, helpers, etc are assumpted to be pre-loaded
//
class Something extends Controller {

         function index() {
                $this->load->library('validation');

        // Set page variables
        $this->view->set("name", NULL);
    
        // ==================================

        // Load the actual page
        $this->view->load('something');

    } // end function

} // end controller class

Code:
// This is the view page. Its just a form, nothing more, nothing less.

<?=$this->validation->error_string; ?>
<?=$this->session->flashdata('msg');?>

<!-- BEGIN FORM -->

<?=form_open('Process_something'); ?>

<h5>Form test</h5>

<p>
<label for="name">Name:</label><br />
&lt;input type="text" name="name" id="name" value="&lt;?=$name;?&gt;" /&gt;
</p>

<p>&lt;input type="submit" value="Submit" /&gt;</p>

&lt;?=form_close();?&gt;

&lt;!-- END FORM --&gt;

Code:
// The processing middleman file
// What I've noticed is that I can't use redirect, I must use the view library in order
// to display everything I need.
// The processing middleman in this exampledoes not prevent the double posting,
// because at this point the address bar is something like
// IE: "localhost/codeignitor/index.php/process_something"
//
// Questions
// How do you prevent double posting in CI?
// I've also noticed that even if you have a middleman processing file, you have to
// recode/retype a majority of code, including page variables.
//
class Process_something extends Controller {
    
    function index()
    {    
        $this->load->library('validation');
        
        $rules['name'] = "required";

        $this->validation->set_rules($rules);

        if ($this->validation->run() == FALSE)
        {
            $this->view->set('name', null);
                
            // ==================================

            // Load the actual page
            $this->view->load('something');

        }
        else
        {            

            // Redirect to same page with success msg
            $this->session->set_flashdata('msg', 'Save succeeded');
            redirect('something');
        }
    }
}

El Forum

[eluser]deviant[/eluser]
One way to do it is to assign each time a form is loaded it is assigned a random ID that is put in a hidden form field and also in the users session vars as a flash variable (only saved for one page load). When you are processing the form data normally check that the hidden random ID from the forms POST data matches the users session var, if it even exists. That way you will still get the POST data message if you refresh but it will not actually do anything.

El Forum

[eluser]Michael Wales[/eluser]
On most all of my forms, I use the same controller for displaying and processing the data, redirecting away upon success.

Code:
$this->load->library('validation');
// My Rules
// My Fields
if ($this->validation->run()) {
  // Perform my database shizzle
  redirect('view_this_data');
} else {
  $this->load->view('display_input_form');
}

A refresh in these circumstances would simply refresh the displayed data.

If you are wanting to load a blank form up again, you could always just toss a middle-man in there, like so:

Code:
$this->load->library('validation');
// My Rules
// My Fields
if ($this->validation->run()) {
  // Perform my database shizzle
  $this->session->set_flashdata('return_path', $this->uri->uri_string());
  redirect('clear_post');
} else {
  $this->load->view('display_input_form');
}

function clear_post() {
  redirect($this->session->flashdata('return_path'));
}

Kind of a round-about way...

El Forum

[eluser]worchyld[/eluser]
I'll try that, thanks... so long as that annoying messagebox doesn't appear again, I'll be happy!