Forum Moderators: coopster & phranque

Message Too Old, No Replies

Refresh protection.

How to stop shopping cart adding again and again and again......

         

Dabrowski

9:19 pm on Jan 5, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



I've got this little problem with a shopping basket I've just written, it all works fine, except if you do something like add an item, it loads the basket.pl script with the options to add whatever product code.

The only problem is if you hit refresh it'll add it again. Not sure the best way to get around this?

Removing items and changing quantities will work fine on refresh, as duplicating those actions would be inconsequential.

perl_diver

5:27 am on Jan 6, 2008 (gmt 0)

10+ Year Member



This is really the same dilema for all pages that display after some post data was sent to the server. An easy and often used method is to have a "thank you" page display then redirect to whatever page you want the user to see. You can accomplish the redirect with meta tags or javascript. Similar to what this forum does, you post a message or reply to one and you get a "message accepted, autorefreshing to......" screen then a redirect back to the thread. That is done to avoid the problem you are dealing with.

Dabrowski

10:00 pm on Jan 6, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Ahh, ok I see. That makes sense, and actually makes the coding easier as you can have a separate script per action, instead of cramming everything into one script. Breaks it up a bit.

So, if I hit refresh on the 'redirecting to thread' page, this will post again?

We'll see.....

perl_diver

1:07 am on Jan 7, 2008 (gmt 0)

10+ Year Member



Yes, if you hit refresh during the redirection it will post again, but you can also make the redirection very fast, there might be other more complicated but more fail-safe ways to do this. Sessions with time-outs, flood control to limit the time between transactions, etc. All of these work but also can be bothersome to your potential users. The redirection is best, few people are going to hit refresh during the redirection and in the end they should have a chance to edit the contents of the cart anyway.

vincevincevince

1:37 am on Jan 7, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



If you use POST for your addition action then most browsers will warn the user when the page is refreshed. I find this warning to be quite sufficient.

I caution you very strongly against what will essentially be a client side redirect. Not only do they look rather unprofessional, they are an accessibility nightmare.

A more recently popular solution is some kind of state identification sent alongside the addition. When you generate the addition form, try setting a hidden variable equal to a md5 digest of current cart contents. When it is submitted, first calculate that md5 digest again, and only if it matches the value in the hidden field do you permit the addition.

Dabrowski

7:49 pm on Jan 7, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



against what will essentially be a client side redirect

I'm inclined to agree with you. After looking into it, the choice is either javascript which you can't rely on, meta refresh which only works after the page loads, or a 302 redirect which is better but as I found you can't set a cookie at the same time.

(I set a cookie for the session ID first time an item is added)

If you use POST for your addition action

I always use GET if I can. POST would be ok, but extremely annoyingly (in IE anyway) if you hit cancel, it doesn't give you the same page back, it displays a 'Web page expired message'. So you either have to hit back until you get to the last non-form page, or renavigate to the site.

What about this: a sequence number stored alongside the session ID in the database. When the basket page loads to add the new item, it must check the sequence number it's given is larger than the one in the database. Assuming it is, add the item and update the sequence number?

Seems a bit more long winded than I'd hoped but can't think of anything better.

Dabrowski

6:42 pm on Jan 8, 2008 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



ok, I found a way that works well:

When the basket adds an item, there's a 'lock' which can be a cookie or in the database. Each product page removes the lock, so you can't add another item until you've actually navigated off the basket page.

Works perfectly......

.....until they told me they wanted a quick 'type your product code here to add an item' box on the basket page! Item wouldn't add because the lock was still on. I had to change this to the sequence method above. A bit more faffy but it works.

Thanks for suggestions.