Hey everyone,
I encountered a bug related to the reCaptcha V2 control not working on a page loaded using the browser's back button after previously submitting the form. The bug only happens when using secure tokens and I was able to reproduce it on the latest versions of Chrome, IE, Edge and Safari. I didn't reproduce the bug on FireFox.
In my application I generate the secure tokens using Ajax, so unique tokens are always passed to grecaptcha.render(), whether the page is loaded normally or from the back button. However, the reCaptcha control only works fine when the page is loaded regularly. When loaded from the back button one of the following behaviors happen:
- the reCaptcha control displays the "ERROR: Stoken expired" message, or
- the reCaptcha control loads ok but the spinner enters an infinite loop when clicking the checkbox
The cause of the bug is a rather strange behavior that most browsers have when loading pages using the back or forward browser buttons and it is related to the fact that they cache iFrame URLs. If a page has a dynamically generated iFrame, that always uses the same URL domain and path but a variable query string, the full URL is cached and reused for the iFrame when the page is visited using the back button.
As an example consider the following scenario related to a page considering a dynamically generated iFrame:
1. You navigate to the page. On this initial visit let's consider that the src of the dynamically generated iFrame is set to
http://example.com?t=12. You navigate away from the page
3. Using the browser's back button, you return to the page
4. On this second visit let's consider that the src of the dynamically generated iFrame is set to
http://example.com?t=2. However, even if the iFrame has a new URL set to it, the browser will still use the old address (
http://example.com?t=1 ) to load it. It does not matter if the iFrame's contents are cacheable or not, its URL will still be cached.
There are some ways to prevent iFrame caching their URLs unfortunately there isn't a single cross browser solution (at least none that I would know about). One such solution is to load the iFrames on a window.setTimeout() event. That works for Safari and Chrome, but unfortunately it doesn't for IE or Edge.
On IE or Edge what works is assigning unique IDs to the iFrames on each request. However since the iFrames are generated from the reCaptcha library, this fix can only be applied from reCaptcha itself.
I wonder if the reCaptcha team is aware of the bug and is planning to do anything about it.
Kind regards,
Florin