Thursday, August 22, 2013

Prevent form reload (login, shopping cart... etc).

Today I was looking through my draft posts and saw this one about preventing form reload, and this is the note I took at the time: "set session variable to empty at form load, set it to something at successful submit, if session variable set when submit clicked, throw error" - well, yes, that was the first thought about it I found on the net, however, after I continued to look, I found that there is a better, more efficient way to do this: the so called Post-Redirect-Get (PRG) method.

You'll find plenty of articles about it, but let me provide you with a very brief summary, a practical implementation of PRG:
1. You collect the user input on your website and send it to the server using the POST method, then do various things with it on server side depending on the type of form (ie. validate login info, update database with user input...etc).
2. Here on the server side, towards the end of your script, you setup a redirect to go to a different page and add attributes to the URL specified in the redirect, attributes that can later on be read using GET (ie. .../yourpage?attribute=1).
3. On the page where you redirected in point #2, use the GET method to read the attribute specified, something around the lines of...:
"if ($_GET['attribute'] == 1) { #do_something }" (assuming you use PHP, but other programming languages have their equivalents too, I'm sure).

Yes, it is that simple! Hope I'm helping someone with this ;)

EDITED: although I still believe PRG is the cleanest solution for this, let me still provide you with a practical solution of the other one, suppose you don't want to revamp your complicated form script. Simply set a session variable's value to some randomly generated meaningless token, add this as the value of a hidden input in your form, then after submitting, when you check for things that have been posted on the next page (or the section of the same page where you do these stuff) to decide what to do next, check first if the session variable's value is the same as the hidden input's. If it is, you can empty the session variable, else throw an error or redirect to whatever script you activate when no change was applied.

The logic behind this is that if you do your first post, the session variable will be the same as the hidden input's, and with the above check, in this case, you'd then empty the session variable. At this stage, you have a still existing hidden input post value, which is that meaningless token, but your session is already empty. This means that the above check will fail when you reload, as while your post values are kept, the session won't be the same anymore. At a new, valid form request however, the session variable's value will be reset to the token, so the request can go through as expected.

No comments:

Post a comment

Dear legitimate commenters, please post your comments below. I'd be happy to receive your feedback; helps me a lot improving, or getting reassurance that I'm doing something really great here.

IMPORTANT! A note to commenters planning on advertising their business in comments: please be informed that I'm NOT going to post your comments but will ALWAYS mark them as SPAM.