scriptygoddess

10 May, 2002

The evil back button

Posted by: Jennifer In: Lessons learned

In working with Lynda (who did MOST of the work! LOL!) on that subscribe to comments script, one of the problems we ran into was with the back button. If after submitting a comment, you hit the back button (which was scary HOW MANY people use it when navigating) it would resubmit the comment and resubmit the email. This has since been fixed, but thought I'd post a little bit about what I learned during this process about back button navigating…

We tried to set a session cookie, didn't work.
We tried to use a variable that was changed once everything was sent, didn't work.
We tried just about everything we could think of.

The only thing that DID work was putting in this line of javascript on the page which basically says – if there's a page to forward this person to – send them there now.

<script language="JavaScript">
<!–
window.history.forward(1);
//–>
</script>

Now what I find most surprising about the fact that this works, is that it's *javascript* which means that it loads AFTER all the php stuff is done… on the CLIENT side. However, without it, the emails get sent out – but that is PHP which is supposedly done BEFORE the javascript is done – because PHP is done on the server – and then it sends you the html page after it's done it's PHP magic, then any javascript gets done on your machine locally.

That being the case… why would this solution work? You'd think that when you hit the back button, since the page is in the client's side cache – that NO php would process again (unless you RELOADED the page – which basically asks for the page from the server again… and the server would process the PHP before sending you the page… etc. etc..) because… PHP is all server stuff.. in fact, you can't even see the PHP code locally…

The only conclusion that I can come up with is this (and please note that I MAY be wrong – I'm just trying to draw a conclusion based on the facts):

When you hit the back button:
Server side stuff IS processed again, BUT variables, cookies, etc. have the same VALUE as they did when the page was first loaded.
Why I think this is true: Because we tried setting a cookie at the time the form was submitted. The value of this cookie was changed AFTER all the stuff had processed. However, at the time the page was originally loaded – the value of the cookie gave the green light for the mail to be sent. Even though that cookie's value had changed… if you hit the back button, it remembered the value of the cookie as it was when the page was first loaded, which gave the green light for everything… and would send the mail a second time. This also holds true for changing values of PHP specific variables…

Since the page is in cache – it will remember any javascript things/processes.
Why I think this is true: Because our solution works. I DON"T think that it processes javascript and then php… but it does seem that way…

8 Responses to "The evil back button"

1 | Lynda

May 10th, 2002 at 2:39 pm

Avatar

I wonder if it's worth it to do more testing? Because you said when people hit the back button on comments you subscribed to, you not only got the email twice, but also got the comment twice.

I can see why we got the comment twice, but I was only receiving one email (this doesn't include the MT email I normally get when a new comment is posted – I would get two MT emails and one PHP-generated email)

We use PHP to echo the values into that form, but the client doesn't know that. It just sees THOSE values in that form and then processes it like a NORMAL form.

And it seems caches like to hold the values of forms for at least a little while for some reason – so I think THAT is why the form got submitted to mt-comments.cgi again.

Again, I don't know if it's even worth spending the time to test it out, but I'm not so sure the PHP *did* send the email out again. I think it just processed the form with the cached values again.

Am I making any sense? LOL. :)

2 | Jennifer

May 10th, 2002 at 3:20 pm

Avatar

yeah, you're making sense… but on my tests I received both emails each time I hit the back button – both the MT generated email, and the PHP generated email. (not sure why you weren't)

3 | Lynda

May 10th, 2002 at 3:36 pm

Avatar

That's why I'm wondering if it's worth further testing… because technically, it shouldn't have sent the email again but SHOULD have sent the form again.

4 | Pete

May 11th, 2002 at 3:54 am

Avatar

My fundamental knowledge of the HTTP protocol / the way browsers work is a little sketchy, but I thought I'd contribute a little bit: (BTW: I'm here via kd http://surreally.com/kd/)

Cookies and session variables are saved on local computers and sent in the headers of the browser's GET command (when it says to the server… hey, fetch me that page)… when you use the back button, AFAIK, it sends the EXACT SAME HEADER as it sent the first time. Therefore, new session variables and cookes will not be sent in the header.

One way to resolve a problem like this within PHP/MySQL would to be to ensure that no two DB entries are identical. If a person posts the exact same name, email, URL, and comment — the odds are VERY good that it was by accident… so you could just not allow it. That fixes the dual comment problem (assuming these comments are stored in a DB… I'm not familiar with GM or MT)…

At any rate, the back button can be a horrible wicked thing when it comes to form submission… ok… I'm going to shut up now.

5 | Jennifer

May 11th, 2002 at 7:27 am

Avatar

Fortunately or unfortunately – MT doesn't use a database. :(

But here's the one thing that I really don't get: I understand that it's using the same stuff in the headers as when it was first loaded – but WHY then does the javascript fix work??

You'd think logically – all the php stuff would be done first THEN the javascript… in this case: the php sends the email notification to those who subscribed to the post. But thats not the case when we add that fix… it doesn't send any mail – and just executes that javascript…

6 | Pete

May 11th, 2002 at 1:16 pm

Avatar

After seeing a little bit how this system works, (I was just babbling in general before) there are a few options that come to mind:

Obviously if the PHP IS being executed the email would send. The other thing about the back button is that it can use the cached output instead of requesting the file again. I honestly have no idea how it decides to request or not request…

However, you're absolutely correct… I can't think of a way that the Javascript will actually work. I think, if anything, it's a coincidence. Maybe something about the javascript is causing the page to be cached? Hmm… I puzzled.

7 | Corey

September 9th, 2003 at 10:42 am

Avatar

Sorry so late to this tread (first post here, and liking what I'm seeing in some of the script work…might I add :) ).

To basically answer the question of why it still post again: Correct, the PHP is never seen again, but remember that the browser never saw it anyway. It only saw the javascript and other HTML. But, this included the PHP variables that were inserted into the javascript or form-elements by the PHP. All the cached page is doing is resending it the way the browser did in the first place – with those elemnts basically echo'd into the HTML and javascript "fill-in-the-blanks". One note on this however Pete, the headers are never recent either (ie…diffrence between PHP header and the <head> tag…example: You can acidently have <head> followed by <head> and most browser will just ignore the second one if nothing is between them. This is not the case in PHP headers as they are actually "openers" so-to speak for the whole page session. Further example: Recall you can often add javascript above a <head> tag, but no such doing before a PHP header normally)

As to correcting this problem, Jennifer came-up with the best idea for all practical purposes. Unless javascript is disabled, it will work like a charm :)

But just becuase I got bored, and maybe someone needs some code to think about how it works (insert laugh here…lol), I came-up with the following solution, below. While not perfect, and requires both javascript and cookies enabled (You can use your own scripts to test for those :) ), it gets the job done. I'll let you figure-out how it does what it does, and why it seems to have repatative script parts (ie: two seperate cookies – one javascript the other PHP – they are neccessary…study). Any questions on it, feel free to email me at corey@maximumscripts.com

_______________________
The form page (Only put a textarea…but you get the idea):

<?
if($HTTP_COOKIE_VARS["FormDone"] == "FormAlreadySubmitted") {
echo 'You have submitted once already!';
}else{
echo '<html><head>
<script language=javascript>
function CheckPage(){
if(document.cookie) {
document.write("You have submitted already!");
}else{
document.cookie="FormIsFilled"+"="+"Yes; expires=Tuesday, 05-Apr-2010 05:00:00 GMT";
setTimeout("document.Form1.submit()",2000);
}}
</script><head><body>
<form name="Form1" action="ThankYou.php" method="POST">
<textarea rows=10 cols=30 name="comments"></textarea>
<input type=button value="Send" onClick="CheckPage()">
</form>
</body>
</html>';
}
?>

=====
In the "ThankYou.php" page:

<?php
setcookie("FormDone","FormAlreadySubmitted",time()+1209600);
?>
Thank You!

_______________________
This not only saolves the problem of the back button..but even if they come to the page from another link or even close the browser and open it in another…no resubmit, unless they delete cookies.
The
echo 'You have submitted once already!';
parts can be replaced by redirects to some page saying how you hate folks trying to send you a million copies of the same thing.

8 | Corey

September 9th, 2003 at 10:49 am

Avatar

Sorry, didn't notice how this would post… The following MUST be all ONE LINE:

document.cookie="FormIsFilled"+"="+"Yes; expires=Tuesday, 05-Apr-2010 05:00:00 GMT";

and do not forget to leave the "setTimeOut(….." or the cookie may not be written before the submit takes place….Thereby defeating the purpose.

Featured Sponsors

Genesis Framework for WordPress

Advertise Here


  • Scott: Just moved changed the site URL as WP's installed in a subfolder. Cookie clearance worked for me. Thanks!
  • Stephen Lareau: Hi great blog thanks. Just thought I would add that it helps to put target = like this:1-800-555-1212 and
  • Cord Blomquist: Jennifer, you may want to check out tp2wp.com, a new service my company just launched that converts TypePad and Movable Type export files into WordPre

About


Advertisements