How to prevent refresh page error while submitting POST form? - php

When registration form submits using POST method and when you refresh the same page then it will prompt for resubmit or resend information. How we can prevent this?

Use post-redirect-get. In short:

You can use ajax. You keep the same php code that you put in another file, and you post the data via ajax.

You can use include a one-time random token in the form. The first time that token is submitted (with other data), an action is taken. Future submissions of the same token have no effect (or just show the same confirmation page), and submissions with blank or invalid tokens are rejected.
This also protects against cross-site request forgery.

Try this:
<?php
if (!empty($_POST)){
?>
<script type="text/javascript">
window.location = window.location.href;
</script>
<?php } ?>
I placed it into prevent_resend.php and then included it after the postdata processing was done.
// ... save data from $_POST to DB
include('prevent_resend.php');
// ... do some other stuff

Related

Page refresh causes form submission [duplicate]

This question already has answers here:
Avoid resending forms on php pages
(6 answers)
Closed 9 years ago.
I have a webpage that contains a form that uses the POST method and references the same page it is on for submission. I am using a PHP include file that contains an if statement that runs when the submit value is set. For some reason though, after one submission, every time you refresh the page it submits the form with the previously submitted data (The browser warns of this before refreshing the page). What causes this, and what could I be doing wrong?
This is expected. You should have the form submit to a handler that has a unique URL, whether it be a query string or a different URI. One solution (of many) would be to change your form action:
<form action="?action=submit" method="post">
<input type="hidden" name="action" value="submit" />
...
and then in the PHP script handle the form, then change the context back to a URL without the hidden query string
if (!empty($_POST['action']) && $_POST['action'] == 'submit') {
// do stuff
header('Location: '.$_SERVER['SCRIPT_NAME']);
die();
}
Note the query string is not actually present in $_POST but we keep it there so browsers don't consider it to be a redirect loop.
i had the same issue with one of my pages.
the reason is that when the browser warns you that it will submit the form again, that means it is going yo be the same exact thing when you click on a submit button.
I did 2 things to avoid it but i am sure there many other ways.
1. Do not let the page echo the form again after succesfull submission of the form.
mine was like this
<?php
if(!isset($_POST['submit'])) {
include(form.php);// you can modify this according to your needs.
} else {
//display your message about what happened with the form.
}
?>
with that approach, your page will not the contaion a form to submit HOWEVER this will not prevent it from submitting on refresh.
2. if the form is submitted create a contoller input that carries a value indication that the form is already submitted. for example , place this into your form:
<?=(isset($_POST['submit']))?"" :"<input type-"hidden" name="submit_stat" value="true" />" ; ?>
and when you process your form when it is submitted check it with your php and make the script act on that variable like this:
<?php
if($_POST['submit_stat']==true) {
//do not process the form here.
//stop your script
}
?>
Another thing you can do is redirect your page to another page other than the page that handles the form. i believe this is the safest one.
Another Way to prevent this is to move the Post Data to Session, redirect, collect Post back from Session and delete Session Post Data.
if(!empty($_POST) && empty($_FILES)){
// move post to session
// redirect to same url (don't forget possible get query)
}else{
// collect post from session
// unset post from session
}
Build this as default and you should never have problems with post data.
Only exceptions are File uploads. In this case redirect *after* post processing manualy.

How to delete $_POST variable upon pressing 'Refresh' button on browser with PHP?

When I press the 'refresh' button on my browser, it seems that $_POST variable is preserved across the refresh.
If I want to delete the contents of $_POST what should I do? Using unset for the fields of $_POST did not help.
Help? Thanks!
The request header contains some POST data. No matter what you do, when you reload the page, the rquest would be sent again.
The simple solution is to redirect to a new (if not the same) page. This pattern is very common in web applications, and is called Post/Redirect/Get. It's typical for all forms to do a POST, then if successful, you should do a redirect.
Try as much as possible to always separate (in different files) your view script (html mostly) from your controller script (business logic and stuff). In this way, you would always post data to a seperate controller script and then redirect back to a view script which when rendered, will contain no POST data in the request header.
To prevent users from refreshing the page or pressing the back button and resubmitting the form I use the following neat little trick.
<?php
if (!isset($_SESSION)) {
session_start();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$_SESSION['postdata'] = $_POST;
unset($_POST);
header("Location: ".$_SERVER['PHP_SELF']);
exit;
}
// This code can be used anywhere you redirect your user to using the header("Location: ...")
if (array_key_exists('postdata', $_SESSION)) {
// Handle your submitted form here using the $_SESSION['postdata'] instead of $_POST
// After using the postdata, don't forget to unset/clear it
unset($_SESSION['postdata']);
}
?>
The POST data is now in a session and users can refresh however much they want. It will no longer have effect on your code.
Use case/example
<!-- Demo after submitting -->
<?php if (array_key_exists('postdata', $_SESSION)): ?>
The name you entered was <?= $_SESSION['postdata']['name']; ?>.
<!-- As specified above, clear the postdata from the session -->
<?php unset($_SESSION['postdata']); ?>
<?php endif; ?>
<!-- Demo form -->
<?php if (!isset($_SESSION['postdata'])): ?>
<form method="POST" action="<?= $_SERVER['PHP_SELF']; ?>">
Name: <input type="text" name="name" /><br />
<input type="submit" value="Submit" />
</form>
<?php endif; ?>
Simple PHP solution to this:
if (isset($_POST['aaa'])){
echo '
<script type="text/javascript">
location.reload();
</script>';
}
As the page is reloaded it will update on screen the new data and clear the $_POST
;)
this is a common question here.
Here's a link to a similar question. You can see my answer there.
Why POST['submit'] is set when I reload?
The basic answer is to look into post/redirect/get, but since it is easier to see by example, just check the link above.
My usual technique for this is:
<?php
if ($_POST) {
$errors = validate_post($_POST);
if ($!errors) {
take_action($_POST);
// This is it (you may want to pass some additional parameters to generate visual feedback later):
header('Location: ?');
exit;
}
}
?>
How about using $_POST = array(), which nullifies the data. The browser will still ask to reload, but there will be no data in the $_POST superglobal.
$_POST should only get populated on POST requests. The browser usually sends GET requests. If you reached a page via POST it usually asks you if it should resend the POST data when you hit refresh. What it does is simply that - sending the POST data again. To PHP that looks like a different request although it semantically contains the same data.
This will remove the annoying confirm submission on refresh, the code is self-explanatory:
if (!isset($_SESSION)) {
session_start();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$_SESSION['postdata'] = $_POST;
unset($_POST);
header("Location: ".$_SERVER[REQUEST_URI]);
exit;
}
if (#$_SESSION['postdata']){
$_POST=$_SESSION['postdata'];
unset($_SESSION['postdata']);
}
You can't, this is treated by the browser, not by any programming language. You can use AJAX to make the request or redirect the user to the same (or another) page.
The "best" way to do this is Post / Redirect / Get
http://en.wikipedia.org/wiki/Post/Redirect/Get
After the post send a 302 header pointing to the success page
I had this problem in an online fabric store, where there was a button to order a fabric sample on the product page, if a customer had first ordered a product and then wanted to order a sample of a different colour their previous order would be duplicated, since they never left the page and the POST data was still present.
The only way I could do this reliably was to add a redirecting page (or in my case in WordPress, add action to "parse_request" for a mock url), that redirects back to the referring page.
Javascript:
window.location.href = '/hard-reset-form';
PHP:
header('Location: ' . $_SERVER['HTTP_REFERER']);
die();
This way you are coming back to a new page, all POST data cleared.
Set an intermediate page where you change $_POST variables into $_SESSION. In your actual page, unset them after usage.
You may pass also the initial page URL to set the browser back button.
I have a single form and display where I "add / delete / edit / insert / move" data records using one form and one submit button. What I do first is to check to see if the $_post is set, if not, set it to nothing. then I run through the rest of the code,
then on the actual $_post's
I use switches and if / else's based on the data entered and with error checking for each data part required for which function is being used.
After it does whatever to the data, I run a function to clear all the $_post data for each section.
you can hit refresh till your blue in the face it won't do anything but refresh the page and display.
So you just need to think logically and make it idiot proof for your users...
try
unset($_POST);
unset($_REQUEST);
header('Location: ...');
it worked for me
I can see this is an old thread, just thought I'd give my 2cents. Not sure if it would fit every scenario, but this is the method I've been successfully using for a number of years:
session_start();
if($_POST == $_SESSION['oldPOST']) $_POST = array(); else $_SESSION['oldPOST'] = $_POST;
Doesn't really delete POST-ed values from the browser, but as far as your php script below these lines is concerned, there is no more POST variables.
This is the most simple way you can do it since you can't clear $_POST data by refreshing the page but by leaving the page and coming back to it again.
This will be on the page you would want to clear $_POST data.
<a class="btn" href="clear_reload.php"> Clear</a> // button to 'clear' data
Now create clear_reload.php.
clear_reload.php:
<?php
header("Location: {$_SERVER['HTTP_REFERER']}");
?>
The "clear" button will direct you to this clear_reload.php page, which will redirect you back to the same page you were at.
If somehow, the problem has to do with multiple insertions to your database "on refresh". Check my answer here Unset post variables after form submission. It should help.
The Post data can be clear with some tricks.
<?php
if (!isset($_SESSION)) {
session_start();
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$_SESSION['postdata'] = $_POST;
unset($_POST); //unsetting $_POST Array
header("Location: ".$_SERVER['REQUEST_URI']);//This will let your uri parameters to still exist
exit;
}
?>
In my case I have used the below trick to redirect user to the same page once the $_POST operation has been done.
Example:
if(!empty($_POST['message'])) {
// do your operation here
header('Location: '.$_SERVER['PHP_SELF']);
}
It is a very simple trick where we are reloading the page without post variable.
I see this have been answered. However, I ran into the same issue and fixed it by adding the following to the header of the php script.
header("Pragma: no-cache");
Post/Redirect/Get is a good practice no doubt. But even without that, the above should fix the issue.
I had a form on my account page which sent data with POST method and I had to store the received data in a database. The data from the database was supposed to be displayed on the webpage but I had to refresh the page after the POST request to display the contents in database. To solve this issue I wrote the following code on account page:
if (isset($_POST['variable'])){
echo '
<script type="text/javascript">
location.href="./index.php?result=success";
</script>';
}
Then on index.php I refreshed the page and sent the user back to my account page as follows:
if (isset($_GET['result'])) {
echo'<script>
//reloads the page
location.reload();
//send user back to account.php
location.href="./account.php"
</script>'
}
You should add the no cache directive to your header:
<?php
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Cache-Control: post-check=0, pre-check=0', false );
header( 'Pragma: no-cache' );
?>
This works for me:
<?if(isset($_POST['oldPost'])):?>
<form method="post" id="resetPost"></form>
<script>$("#resetPost").submit()</script>
<?endif?>

verify entrance source in php

I have a link on the page that opens a contact form in a modal window.
How can I verify that the user clicked on the link to access the contact form, and did not go to the page directly. I don't want users or bots inadvertently browsing to that page.
Thanks in advance!
You can check for $_SERVER['X_HTTP_REQUESTED_WITH'] header, which will be xmlhttprequest whenever it's an ajax request
You can use the referral url (you can access this url in PHP using $_SERVER["HTTP_REFERER"]) but you can't rely on it. First because it can be changed using a very simple script and second because that field is not always filled.
Another method is to use session to store the last visited page and then check this in your contact page. Anyway this method will also fail if the user see another page before access to the contact form but the page which you want the users start with was already loaded.
You can send a variable with it like
Contact Me
and in the modal test weather it set or not
if(isset($_GET['co'])):
//show the form
else:
//redirect
endif;
or you can use jquery to select that link and sends a variable posted with it like
Contact Me
$('.contact').click(function(){
$.post( 'contact.php', { direct: 'no'},function()
{
//call modal from here
}
);
});
then test if direct = no
if($_POST['direct'] == 'no'):
//show the form
else:
//redirect
endif;
and the jquery solution is more reliable
Sorry I was wrong
Have a form with a hidden field that contains a token, and validate that token with the session on postback.

How to send $_POST content without submit bottun

I have form inputs to send to another page to check on and validate them, and in case of errors I have to redirect the user back to the page where he/she filled the form.
So I need to send the content of $_POST back to refill the inputs to avoid refilling them manually...
How can I do that??
Here are two options:
1) Have the PHP script redirect back to the page with the form, with the form values in the URL as GET variables. You can then use those to refill the form.
2) You can send a POST request via jQuery without requiring the user to leave the page. See here: http://api.jquery.com/jQuery.post/ . With this, you can check the user's input in the PHP script, and only redirect them if their input is valid. This saves you the trouble of refilling the form. You can use it like this:
$.post("myphpscript.php",
{ someData: someValue, someMoreData: anotherValue },
function(returnData) {
// do stuff here on return
});
In myphpscript.php you can get the post values as $_POST["someData"] and $_POST["someMoreData"]. The function is what happens when the PHP script returns, and returnData is what the PHP script echoed.
If I'm correct you want to check your POST-values and if they are invalid input, you want the user to be directed back to the original page and fill the input-fields with the POST-values.
<input type="text" value="<?php echo (isset($_POST["text"] ? $_POST["text"] : "") ?> />
This checks if the POST-var is set, if so, it sets the value of the input-field to the value of the POST-var, else it sets the value to empty
An alternative to excellent answers posted is to store these values into the session and access them from there.

Retaining data in HTML form

I have an HTML form. Let's say I fill out all the fields and submit it (PHP script runs here).
Then I want to go back to the form using "Back" button of my browser.
What I see is the empty form.
What do I do to have the entered data retain on the page after I come back to it using "Back" button of the browser?
Thank you!
If you use the "Back" button of your browser then your browser is responsible for re-populating your form data.
Usually that functionality is handled by the browser, however if you want to "force" the fields to always be pre-filled with the user's data, you can store the $_POST data in a session variable and use that to load the form.
Example:
// submission page
session_start();
if(isset($_POST)){
// save the posted data in the session
$_SESSION["POST"] = $_POST;
}
Then on the actual form page, you can check to see if session data exists. It won't if the form is being loaded the first time, but it will if the user submits the form and then presses the browser back button:
// form page
session_start();
if(isset($_SESSION["POST"])){
// previous POST data has been saved
// build the form with pre-defined values from $_SESSION
...
} else {
// no previous data
// build the form without pre-defined values
...
}
Note that you must call session_start() before outputting any HTML.
Store the value in a session
session_start();
//form so that you have all the potential forms in a single session array
//form_1 to identify the form in question
if(!empty($_POST)){
$_SESSION['forms']['form_1'] = $_POST;//if this is for the public internet, then I would really consider making sure that the posted data matches the received data... (and that its comming from YOUR form), which is way too long to post here...
}
then on the form page
<input name="flowers" value="<?php echo if(isset($_SESSION['forms']['forms_1']['flowers'])){ echo htmlspecialchars($_SESSION['forms']['forms_1']['flowers']);} ?>" />
obviously the above can be simplified, but for a example's sake it's better this way.
(make sure to clean out the old form data eventually)
You can potentially store the data in the session, and re-populate it back using PHP sessions. You should create a separate back button that takes you to the previous page.
Example:
Storing data:
$_SESSION['data'] = $_POST['item1'];
In the HTML Forms:
<input type="text" name="someinput" value="<?=$_SESSION['data']?>" />

Categories