Page 1 of 2

send POSTDATA back and forwar how to prevent ??

Posted: Wed Jan 18, 2006 4:27 am
by duk
i need some help here..

i have done a form... with 3 functions working as 3 pages...

the first page... function page1(); send data the scrit check if the first submit button was pressed if everything ok goes to function page2();

but when i go back... he ask me that if i want to send POSTDATA but i dont want him to do this... i want him to go back without asking nothing...

Posted: Wed Jan 18, 2006 4:32 am
by raghavan20
It is by default submitting using POST requires you to answer to that dialog, if you want to avoid it, you have to use GET.

If you want to go to a previous page, capture the state and provide a link, you cannot change browser's default behavior.

Posted: Wed Jan 18, 2006 4:38 am
by duk
what i was thinking was...

clean all buffer of the browser... and then when you do back... he dont have data to POST so he dont need to ask for posting data to previous page...

i was trying flush and ob_clean... but without good results...

Posted: Wed Jan 18, 2006 9:29 pm
by feyd
php has no authoritative control over the browser's actions.

As Roja has talked about previously, you can post to a page that performs the processing, but instead of giving output from that page, it redirects to a second script that displays the results. Hitting back will return to the original page.

Posted: Wed Jan 18, 2006 10:20 pm
by Christopher
feyd wrote:As Roja has talked about previously, you can post to a page that performs the processing, but instead of giving output from that page, it redirects to a second script that displays the results. Hitting back will return to the original page.
This is the standard way to handle this. Once page1 has determined that the submission is correct then redirect to go to page2 by setting the HTTP headers:

Code: Select all

header('Location: page2.php');
// you may want to do exit(); after setting the header depending on your logic
make sure you have not output anything before you do the above as headers need to be sent before any output.

Posted: Thu Jan 19, 2006 12:56 am
by josh
feyd wrote:Hitting back will return to the original page.
but pressing refresh still resubmits the form :? I get duplicated in my DB every day because of this

Posted: Thu Jan 19, 2006 6:10 am
by raghavan20
Mozilla calls it rightly as reload rather than refresh.
But if you remove all the parameters in the URL and type enter, you will get a new page without POST or GET variables.

Posted: Thu Jan 19, 2006 7:22 am
by foobar
jshpro2 wrote:
feyd wrote:Hitting back will return to the original page.
but pressing refresh still resubmits the form :? I get duplicated in my DB every day because of this
Then your db-insertion code is faulty.
It should check for duplicates by default or you should define your unique/primary keys in such a way that it's impossible to insert a duplicate.

Posted: Thu Jan 19, 2006 8:45 pm
by cent
2 ways that I've done...

First way:
1. create a unique field in your table.
2. on the HTML form page, create a hidden input field with a uniqueid.
3. on the PHP script which gets the post try writing that hidden field to your table along with the other data. if its the first time for the post, then it should be written fine. on subsequent posts (reloads, clicking back and submitting again) there will be a record with that random field already and it will fail and no be saved.

Second way:
1. test for a session variable.
2. if the session variable doesn't exist, then write the data to the table. then set a session variable to prevent reposting. go to your thank you page.
3. if the session variable exists, just skip and go to your thank you page. subsequent posts will be skipped.

you mileage may vary.

best,
cent

Posted: Thu Jan 19, 2006 10:30 pm
by josh
foobar wrote:your db-insertion code is faulty.
incorrect, there can be legit "duplicated" (that is records with the same value for the name field),

I'm well aware of the methods in preventing duplicate records, the problem here is the prompt to resend the post data (although I do like the idea of the token in the form), from what I know there is no way to prevent it other then using a javascript redirect rather then a header redirect.

Posted: Fri Jan 20, 2006 3:03 am
by duk
off course there is...

before you insert anything in your data base you can make a simple check.. if for example lets imagine... the column "name", you can check if the name=user already exist if yes just simply dont insert nothing...

anyway there is a lot of possible ways to prevend a refresh to insert again the same data to the database

Posted: Fri Jan 20, 2006 4:07 am
by raghavan20
jshpro2 wrote:
foobar wrote:your db-insertion code is faulty.
incorrect, there can be legit "duplicated" (that is records with the same value for the name field),

I'm well aware of the methods in preventing duplicate records, the problem here is the prompt to resend the post data (although I do like the idea of the token in the form), from what I know there is no way to prevent it other then using a javascript redirect rather then a header redirect.
The code is not faulty. What you can do is, you can set a cookie or a session variable which confirms that an operation has been carried out so you cannot do it again. Usually, I use this to disable submit button.

Most of the time, primary keys are generated using NULL in sql statements so I think this cannot stop legitimate duplicate entry if all the fields are valid as it will.

I am thinking of something like this...
1. when doing an operation, store the entire row in the session as an array
2. When doing the same operation again, check whether the entire row is same as the stored array.
if yes, display error message,
else do the operation, store the new row used in the operation

This should not consume more memory because at any point of time you would have only one row stored in session variable.



Look at the PRG pattern to solve this problem suggested to me in another thread by Roja.

Posted: Fri Jan 20, 2006 9:58 am
by Chris Corbyn
jshpro2 wrote:
foobar wrote:your db-insertion code is faulty.
incorrect, there can be legit "duplicated" (that is records with the same value for the name field),

I'm well aware of the methods in preventing duplicate records, the problem here is the prompt to resend the post data (although I do like the idea of the token in the form), from what I know there is no way to prevent it other then using a javascript redirect rather then a header redirect.
A header redirect outright stops this behaviour. I'm confused :?

form.php

Code: Select all

<form action="foo.php" method="post">
<input type="text" name="foo" /> <input type="submit" name="submit" value="Send" />
</form>
foo.php

Code: Select all

<?php

if (!empty($_POST['foo']))
{
    insert_data_into_db();
    header('Location: done.php');
}
else echo "Not allowed here!";

?>
If you hit the back button after submission it'll just go back to form.php since the browser request was redirected by a Location header.... it won't go back there. If you try to go to foo.php directly it'll be quite inert. Equally the POST data would have been lost in foo.php before the redirect so that's not going to reappear neither.

Posted: Mon Jan 23, 2006 11:05 pm
by d3ad1ysp0rk
jshpro2 wrote:
feyd wrote:Hitting back will return to the original page.
but pressing refresh still resubmits the form :? I get duplicated in my DB every day because of this
No, it won't. There are three pages.

form.htm, process.php, and success.php:

form.htm:

Code: Select all

<form action="process.php" method="post">
<input type="text" name="Title" /> Story Title<br/>
<input type="text" name="body" /> Story Body<br/>
<input type="submit" name="submit" value="Post." />
</form>

Code: Select all

<?php
if(empty($_POST['title'])){
  header("Location:form.htm"); //optionally send with get parameters that throw an error, or set a session error.. or whatever
}

include("db.inc.php");
$db = new database;
$sql = "INSERT INTO posts(id,title,body,date) VALUES('','".$_POST['title']."','".$_POST['body']."',NOW()"); //No data validation = bad.. but it's an example
$db->execute($sql);

//everything went well (you should be doing error checking before this)
header("Location:success.php");
?>

Code: Select all

<?php
echo "Congrats! You submitted news!";
?>
Now, if they hit refresh from here, they get the same congratulations message (it could be an html page, it doesn't matter). If they try to hit back, they go straight to the form where they can fill out more news if their heart so desires.

Either way, no dupes.

Posted: Mon Jan 23, 2006 11:28 pm
by josh
From my experience after the header redirect the user can still refresh to send post data but it fixes the back button. At least in the database I was referring to earlier when data is duplicated the old data becomes orphaned from it's counterpart in another table, so that's a solid way to weed out the 'bad' rows.