The problem is that Gecko based browsers don’t always invalidate its cache on POST requests. People would submit a comment, have visual confirmation that the comment wasn’t there, press the back button, and then click submit again.
So today I implemented a pair of low-tech solutions. The first is that I now append a single ? at the end of the URI specified in the location header and before the fragment identifier. From the browsers perspective, this identifies a different resource. From the server’s perspective it resolves to the same page. This should avoid any client caching issues, people will see what they just posted, and I doubt many will even notice the subtle change in the URI. Things will simply appear to “just work”.
Additionally, I now disable the submit button on the way out... making it a bit more difficult to simply click back then submit. The submit button should be re-enabled in thirty seconds or so, and the hope is that that gives the high tech workaround one opportunity to kick in.
I did this the other day, but it was because I got a 500 after I hit submit.
That breaks when the commenter discloses the resulting URI to others; e.g. blogs it or submits it to Reddit. People end up visiting the ? URI first, leaving you with the same problem. Perhaps append a timestamp?
If you see this again, please leave a comment to that effect. I try to log all such events, but only keep said logs for about 24 hours. At the moment, the log is clean (if you don’t count the 2,214 spam posts which occurred during that time).
Perhaps append a timestamp?
Seems to me that runs into the same issue. In any case, the issue is slight because if somebody wants to blog a comment that they made and said URI contains an extra ?, the page that the user sees will still be the same.
I just got one on my last comment. An XML file with some data about a Module error.
btw, I’m not sure we would have fixed this issue in Firefox 2, even if we had a patch. We had pretty strong requirements about avoiding web compatibility changes from Firefox 1.5.
The solution is simpler and cleaner than that. Submit the new comment to an URI that produces no output other than an http redirect (i.e. stores the comment in the db and redirects to the result page). Gecko based browsers will never store this intermediate URI in history (or cache). Users can then use back and forward browser buttons with no duplicate posting.
OK, got it. My latest fix caused a regression for the non-OpenID authenticated posts. Should be better now.
We had pretty strong requirements about avoiding web compatibility changes from Firefox 1.5.
Frankly, that scares me. Hopefully that doesn’t ultimately doom Firefox 1.5 to be the next Netscape 4.
Submit the new comment to an URI that produces no output other than an http redirect
You wouldn’t believe how many redirects are in play with an OpenID post, and yet the problem remains. If the goal is to start at page X, redirect n times, and end up back at page X, the value of n doesn’t much matter; the trick is still to get Firefox to actually fetch page X at the end. Or, in my case, X’ (or should I say X?).
I append a ? at the end of the URI specified in the location header and before the fragment identifier. This identifies a different resource for the browser, resolves to the same page for the server. I also disable the submit button on the way out...
The issue is slight because if somebody wants to blog a comment that they made and said URI contains an extra ?, the page that the user sees will still be the same.
I think you missed Jim’s point. What he was saying is that if someone visits a URI with an extra ?, and then decides to leave a comment, your workaround will not work, because the URI they fetched the first time already had the ? appended.
Appending a timestamp in the query string instead of just a null query string would ensure that the redirection target always differs from the URI that the visitor hit on their way in.
Appending a timestamp in the query string instead of just a null query string would ensure that the redirection target always differs from the URI that the visitor hit on their way in.
I buy that. But on the other hand, would prefer to solve 99% of the problem cleanly than 100% of the problem in an ugly manner. The problem is fairly rare, the recent uptick in duplicate posts that triggered my action wasn’t Firefox’s fault at all, but was the problem that I introduced and affected Rob; not all browsers share this problem, and I now have a total of three counter-measures in place.
I think I got the reason. Yesterday, when posting the comment, I was presented with an error page. I had the natural reaction: go back and resubmit. This second time, I got again an error but, when going back, the comment form page had a message about rate throttling. I assumed the comment got through despite the error.
Sorry for not having the exact error text. Yesterday I had it, but rate throttling prevented me from commenting. I’m using FF 1.5. The error was a very simple XML document, with a code and a message.
You seem opposed to redirecting after the POST, is that right? If so; why? After the POST, you can redirect to any URI, including a timestamp argument and a fragment identifier if you will. That will surely invalidate the page in whatever cache it may be in, but if Firefox only doesn’t invalidate on POST (but does on GET), the redirect don’t need a timestamp argument at all; a fragment identifier to move the viewport to the posted comment will do.
Oh, and hitting submit with Opera now yields a disabled submit button and nothing else. Preview and then submit works, though.
Why not filter your comment entries as unique for a post ?
I actually look for uniqueness across the last 5 posts or 15 minutes, which ever is greater, plus 72 hours of spam. But based on your comment, I increased the weight I assign to such posts.
Sorry for not having the exact error text.
It looked like a trackback response with an error of 0 and a message indicating that ‘file’ was not in module. Fixed yesterday. Sorry about that.
Yesterday I had it, but rate throttling prevented me from commenting.
Rate throttling is another factor in the weighting that I mentioned above. Those with openids get an additional ‘strike’. I just added code so that those with registered ids get two.
You seem opposed to redirecting after the POST, is that right?
There actually is a number of redirects.
/blog/2007/10/03/Preventing-Duplicate-Comments redirects to http://www.myopenid.com/server?... which redirects to http://intertwingly.net/...?&xid=... which redirects to http://intertwingly.net/...?#c...
Oh, and hitting submit with Opera now yields a disabled submit button and nothing else.
Until I can get the disable submit working as I like, I’ve commented it out. You might need to force a refresh of /js/comment_form.js
The problem is definitely a Gecko issue, Jeff Atwood is seeing it on Movable Type, which I presumed to be Wordpress because I see it all the time on Wordpress blogs.
Strange that the bug is still marked “unconfirmed” and that nobody is assigned to fix it. Sounds like a pretty small patch to me. I’ve got zero knowledge of the Mozilla codebase, though, so I might of course be completely wrong.
The Linux Driver Project We are a group of Linux kernel developers (200+) and project managers (10+) that develop and maintain Linux kernel drivers. We are willing and able to sign NDAs as long as we are able to create a proper GPLv2 Linux kernel...