Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi there!
We have a webstore that I created -- all the scripts are written in perl. It's basically a modified version of checkout.pl.

Every time a user comes to the site they're automatically assigned a 'shopping cart' id. What is happening now is that if a user clicks on a link and Internet explorer sometimes uses a 'cached' page instead of executing the perl script again. Because of this a user may add an item to their shopping cart, then click around the site, then add another item to their shopping cart, and because it is an 'old' page, the first item that they added isn't there because the underlying html is working with two different shopping cart ids.

How can ask you force a link to 'refresh' and not use the cache? Is this maybe a javascript question? I'm a perl person so thought I'd come here for some suggestions.

Thank you!!

  • Comment on How to force perl script to be refreshed

Replies are listed 'Best First'.
Re: How to force perl script to be refreshed
by tachyon (Chancellor) on Oct 10, 2004 at 11:05 UTC

    It sounds like you need to rework your logic. You can *reduce* caching of pages using headers, but browsers are free to (and do) ignore these. See Control of cache and overkill anti-caching CGI headers. The main problem with hyper agressive anti caching is that it is very Back button (read user) unfriendly. On one of the Internet banking sites I use if you try to use back you get a blank can't refresh page. OK so you click *Forward* only to be greeted by the same thing! The >only< way out is back, back back until you get to a cached page - turns out to be the login page. Secure it may be. User friendly it is not.

    There are workarounds. Evidently you must be storing a sessionID in a hidden field on the page. If you additionally (or only) used a cookie (also storing the sessionID) you can detect and correct this issue as you will have the current sessionID when the user submits their addition to the cart - this must and always will hit the server. 90%+ of clients will be allowing cookies. Many shopping sites insist on cookies as they allow users a lot more freedom and simplify maintaining state. With session cookies a user could add an item, go to their bank, check their balance, return, add more items to the still current cart and then checkout. You just can't do that with hidden field sessions. You do need to timeout the sessions of course, and only make a new session when required.

    cheers

    tachyon

      What browser do you use and what does that page do if you click Reload? Also are you sure this happens always? I do believe this is a problem only if the page you are trying to return to resulted from a POST.

      Jenda
      We'd like to help you learn to help yourself
      Look around you, all you see are sympathetic eyes
      Stroll around the grounds until you feel at home
         -- P. Simon in Mrs. Robinson

Re: How to force perl script to be refreshed
by cbraga (Pilgrim) on Oct 10, 2004 at 13:56 UTC
    The correct header to send out is Cache-Control: no-cache, no-store. This will cause the back button to work correctly, when you press back the page will be fetched again from the server. Don't do anything else (expires in the past, pragma) since they'll only confuse the browser and probably screw up the back button.

    ESC[78;89;13p ESC[110;121;13p

      The problem with back buttons, refreshes, and shopping carts is that if a refresh is forced on the add item post page you get a duplicate item in the cart.

      cheers

      tachyon

Re: How to force perl script to be refreshed
by TedPride (Priest) on Oct 10, 2004 at 23:15 UTC
    Use cookies to store the session ID at the same time it's assigned to the user the regular way. If at some point the cookie ID doesn't match the web page ID, revert to the cookie ID. If the cookie ID is lost, revert to the web page ID. I'd personally also store the IP address for those times when both IDs are lost.

    You might also be interested in the following:
    http://www.htmlgoodies.com/tutors/refresh.html

Re: How to force perl script to be refreshed
by Prior Nacre V (Hermit) on Oct 11, 2004 at 10:04 UTC

    You can stop the browser reading a cached page by making all URIs unique.

    You can do a quick-and-dirty by adding a random number to the URI's query string (as shown in test output below).

    [ ~/tmp ] $ perl -wle 'use strict; print join("", "fred.pl", "?dummy=" +, rand)' fred.pl?dummy=0.67350901065311 [ ~/tmp ] $ perl -wle 'use strict; print join("", "fred.pl", "?dummy=" +, rand)' fred.pl?dummy=0.079789433236332 [ ~/tmp ] $ perl -wle 'use strict; print join("", "fred.pl", "?dummy=" +, rand)' fred.pl?dummy=0.844672383115725 [ ~/tmp ] $ perl -wle 'use strict; print join("", "fred.pl", "?dummy=" +, rand)' fred.pl?dummy=0.288386549874307 [ ~/tmp ] $

    To guarantee uniqueness, you'll need to replace rand with a call to something that will return a unique value - possibly a custom-built application which returns a unique value, reading the nextval from an Oracle sequence or something along those lines.

    Regards,

    PN5

      using the epoch works just as well as random numbers.
      Perl: my $time = time; JavaScript: var now = new Date(); var epoch = now.getTime();
      Attach either of those to the end of a link and the browser will no cache the output.