How to prevent form resubmission when page is refreshed (F5 / CTRL+R)
Solution 1
Use the Post/Redirect/Get pattern. http://en.wikipedia.org/wiki/Post/Redirect/Get
With my website, I will store a message in a cookie or session, redirect after the post, read the cookie/session, and then clear the value of that session or cookie variable.
Solution 2
I would also like to point out that you can use a javascript approach, window.history.replaceState
to prevent a resubmit on refresh and back button.
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
Proof of concept here: https://dtbaker.net/files/prevent-post-resubmit.php (Link no longer works)
I would still recommend a Post/Redirect/Get approach, but this is a novel JS solution.
Solution 3
You can prevent form resubmission via a session variable.
First you have to set rand()
in a textbox and $_SESSION['rand']
on the form page:
<form action="" method="post">
<?php
$rand=rand();
$_SESSION['rand']=$rand;
?>
<input type="hidden" value="<?php echo $rand; ?>" name="randcheck" />
Your Form's Other Field
<input type="submit" name="submitbtn" value="submit" />
</form>
After that check $_SESSION['rand']
with textbox $_POST['randcheck']
value
like this:
if(isset($_POST['submitbtn']) && $_POST['randcheck']==$_SESSION['rand'])
{
// Your code here
}
Make sure you start the session on every file you are using it with session_start()
Solution 4
This method works for me well, and I think this is the simplest one to do this job.
The general idea is to redirect the user to some other pages after the form submission, which would stop the form resubmission on page refresh. Still, if you need to hold the user on the same page after the form is submitted, you can do it in multiple ways, but here I am describing the JavaScript method.
JavaScript Method
This method is quite easy and blocks the pop up asking for form resubmission on refresh once the form is submitted. Just place this line of JavaScript code at the footer of your file and see the "magic".
<script>
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
</script>
Solution 5
I use this javascript line to block the pop up asking for form resubmission on refresh once the form is submitted.
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
Just place this line at the footer of your file and see the magic
Related videos on Youtube
user701510
Updated on December 15, 2021Comments
-
user701510 over 2 years
I have a simple form that submits text to my SQL table. The problem is that after the user submits the text, they can refresh the page and the data gets submitted again without filling the form again. I could redirect the user to another page after the text is submitted, but I want users to stay on the same page.
I remember reading something about giving each user a unique session id and comparing it with another value which solved the problem I am having but I forgot where it is.
-
Marcel almost 13 years
-
Adam almost 8 yearsWhy do you not want to redirect user to another page?
-
Eugen Konkov over 6 years@Adam: Because this is excess to do another request to the server which in turn will fetch some data from DB again. But this is resource wasting because we already fetch all required data while processing
POST
request -
Adam over 6 years@EugenKonkov in the PRG pattern, you would just redirect to a page that shows a success message. No further fetching from DB needed.
-
Eugen Konkov over 6 years@Adam: You also may display the whole record which is created by
POST
ing data. In this case you need toSELECT
it from DB. For example when you create the invoice you are redirected to/invoices/53
which display the whole invoice instead of just 'success' -
ICW over 4 years@Marcel OP wants to stay on the same page. Redirect is not an option as it is literally the act of leaving the page.
-
Ricky Levi about 2 yearsI used your comments and made the redirect with the same URL as the form uses. since this is a
POST
request there's nothing in the query string, therefor i useLocation: https://domain/same_script_path
... - and i stay in the same page just w/o the form data
-
-
jacoz over 11 yearsTake a look at en.wikipedia.org/wiki/Post/Redirect/Get ! This is the right approach
-
aLearner almost 11 yearsThanks for sharing but this doesn't seem to work. Refreshing the page does indeed resubmit the form for me. Perhaps I'm missing something?
-
Moob almost 11 yearsRefreshing the page will resubmit everything but we choose only to process the submission data if its different from the data sent last time (which we store in the session var 'messageIdent'). Are you processing your form submission within the 'if messageIdents are different' clause (ie where 'do_your_thang()' is)?
-
aLearner almost 11 yearsThanks for your reply. I ended up just implementing the Post / Redirect / Get pattern, so, I don't remember now what exactly was tripping me up. Thanks again for circling back, though.
-
Gavin almost 10 yearsUnsetting $_POST doesn't affect form resubmission at all, at least not in Chrome.
-
Fernando Silva over 9 yearsI actually just wrote something similar to this, but didn't go through the trouble to create a password, I just enumerated my forms (eg: steps 1-5), so if they're equal we're cool to move on, else don't save to db or send emails. But let the user land wherever it takes him.
-
JWP over 9 yearsThis makes chrome unusable for development where business is requiring only a post!
-
Nick Rice over 9 yearsThis is just repeating the same answer that someone else gave years earlier. (In fact two others!)
-
TheSatinKnight over 8 yearsThis method is not meant to block resubmission ... but to Detect resubmission so you can alter your code to not "do" whatever you would do if this were a fresh submission. In other words: With this method you can detect the "original" submission and place your data. If it's NOT original, don't place your data. Either show a "dupe attempt" warning or perhaps show a "confirmation" instead.
-
Julio Popócatl over 8 yearsI think this is a better solution than reload the page, since i show a message when post succesfull and reloading the page will delete the message. this works grate for me, you also can use a uniqid
-
Adam almost 8 yearsIf you use the PRG pattern, then you actually leave the page right? Wasn't the question how to make things work when not redirecting?
-
Sandhu over 7 yearsIt will not work. When user go to back page it perform the setting up of POST variables once again.
-
Nikolay Bronskiy over 6 yearswe can use
<input type="hidden" name="randcheck" id="randcheck" value="<?php echo microtime(); ?>" />
instead -
Savoo over 6 yearsYes we can use microtime() as well as time() also instead of rand() , whatever function or variable that gives different value we can use it. BUT make sure that you set that value to SESSION variable. here SESSION is must to check with randcheck field and to prevent from resubmit form.
-
wkille about 6 yearsFor this to work you must have started a session by adding
session_start();
at the beginning of the file. w3schools.com/php/php_sessions.asp says Note: The session_start() function must be the very first thing in your document. Before any HTML tags. -
Csongor Halmai over 5 yearsUnfortunately, with PRG, when the user opens more tabs from the same session then they can send Content#1 from the first tab and the Content #2 from the second tab. Now the session stores only the most recently sent content so Content #1 can be sent again from the first tab and Content #2 again from the second one, and so on. So, you should store the hash of not just the most recent conent but that of all of them while the session lasts. Or, you can delete the stored hashes after a tolerance period or if there are too many of them.
-
Péter Vértényi about 5 yearsWould be nice a version of this that can't be disabled from the client side, but it is short, easy, fast... and do what it needs to do. Keeps the history so the user can navigate back, without resending post.
-
Gufran Hasan about 5 yearsThanks, @dtbaker, it's awesome :)
-
donutguy640 about 5 yearsIt seems to me that if you redirect to the same page, then $_POST is cleared. As I understand it, that was the desired effect. That was MY desired effect, anyway. I think the answer would be better if it made that explicit, though.
-
tess hsu almost 5 yearsTks, this is work perfect for me, it just had to create 404 page avoid user missunderstanding
-
user4906240 almost 5 yearsSimply Amazing. Thankyou
-
Maurice over 4 yearsWorks well, my only recommendation is to make sure you enable strict error testing so you're catching errors locally while developing, otherwise they can go unnoticed.
-
ICW over 4 yearsDoesn't answer the question. Not sure why it's the accepted answer.
-
ICW over 4 yearsIt makes no sense to say "You should use PRG" to answer this question when it is literally impossible to use PRG and also stay on the same page.
-
Vo Thanh Tung over 4 yearsit doesn't work in safari, it changed href but still keep the data with post request to submit
-
denoise over 4 yearsshouldn't the session variable be cleared after checking if the session and post vars match?
-
Jassar over 4 yearsThis worked for me thank you! Why do you recommend the PRG approach?
-
Hmerman6006 over 4 years@denoise I believe the idea by @Savoo is that after
$_POST
of the form data the same page reloads re-setting the session and post variables. Also creation of variables should takes place after checking if the variables match. Thereforeunset
is not needed. -
garry man about 4 yearsAnother solution is to add a location header in your backend POST handler, which will automatically redirect to your POST callee page. For example if you're on PHP you could do header('location: yourpage.php')
-
megyptm about 4 yearsThanks, it's Amazing, i test its working very well with google chrome
-
Nico Haase almost 4 yearsPlease add some explanation to your answer such that others can learn from it - where does
$everything_fine
come from? -
Nico Haase almost 4 yearsPlease add some explanation to your answer such that others can learn from it - why is that
unset
call needed? What would happen if you skipped it? -
Nico Haase almost 4 yearsIf you duplicate other people's answers, you should at least add some explanation to your answer to make it interesting
-
Nico Haase almost 4 yearsWhat's the reason for using
unset
? Please add some explanation to your answer such that others can learn from it -
Loenix over 3 yearsUsing PRG, you lose context, it's a bad solution for me. We should not do that.
-
David over 3 years@NicoHaase
$everything_fine
is the boolean result of form-validation. If the form is not validating then it shall be usually displayed again with a hint what to correct, so that the user can send it again. Therefore the$_SESSION['uniq']
is created again too if a corrected form is desired. -
Nico Haase over 3 yearsPlease add all explanation to your answer by editing it
-
David over 3 years@NicoHaase It's not my answer, what I did describe is obvious in the code of the answer.
-
BodgeIT over 3 yearsWorked perfectly on a system where we couldn't get the post/redirect/get approach to work. Very nice, thanks.
-
Haider Ali J Al-Rustem over 3 yearsThat solved the issue for me. Does this method have any downsides though?
-
amarinediary about 3 yearsI presumed that, anybody using a browser without javascript would still encounter the same issue. Perhaps stackoverflow.com/a/38768140/3645650 is more suiting.
-
NcXNaV almost 3 yearsI am currently using this kind of method, with tokens. However, this will create a problem on multi-tab submission. Since it will create new
rand()
on each tab, and overwrite the session value, this means older tabs opened is no longer valid. Any suggestion? -
Utmost Creator over 2 yearsCould you please compare these approaches? 1 AJAX request 2
Post-Redirect-Get
(PRG
) pattern 3 JSwindow.history.replaceState
IMHO:1 AJAX
is probably the best solution (but requires some time to prepare the form validation to work with the DOM elements)2 PRG
is not always suitable(if you have validation, then you will need to use the intermediary thing to pass the errors with a session that is not that good)3 JS
solution seems like a crutch,isn't it? I would do appreciate any comments/critic about it. Let me know the pros/cons of each. Are there any downfalls using AJAX? -
cmd05 about 2 yearsthis is so much neater