Search code examples
jsonrecaptchaunexpected-token

reCAPTCHA Unexpected token in JSON at position 0


We use reCAPTCHA ver 2 as checkbox "I am not bot". Since from 2020-11-05 19:23:00Z during our page loading we get exception:

recaptcha__ru.js:211 Uncaught (in promise) SyntaxError: Unexpected token   in JSON at position 0
    at JSON.parse (<anonymous>)
    at recaptcha__ru.js:211
    at recaptcha__ru.js:209
    at Array.<anonymous> (recaptcha__ru.js:132)
    at Array.<anonymous> (recaptcha__ru.js:208)
    at GM.$ (recaptcha__ru.js:211)
    at Array.<anonymous> (recaptcha__ru.js:253)
    at QS.next (recaptcha__ru.js:416)
    at y (recaptcha__ru.js:355)

Exception occurs in https://www.google.com/recaptcha/api2/anchor?ar=1&k=6LcOyt8ZAAAAAD9WJMwwwvgvSGp8Bi0zWYS-FMX5&co=aHR0cDovL2JsYWNrYmlyZDo0ODA4MA..&hl=ru&v=1AZgzF1o3OlP73CVr69UmL65&size=normal&cb=a79dhaz0etu

enter image description here

Our page has not been changed. The reCAPTCHA breaks unexpectedly in one moment. On other page reCAPTCHA is still working (may be it is important the working page is a embedded inside iframe).

Any hints? What went wrong?

UPDATED

We try to isolate reCAPTCHA inside iframe in our JSP page as @user2384519 suggested:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
<%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Captcha test</title>
<script>
    function extractRecaptchaResponse() {
        var c = document.getElementById('g-recaptcha-isolator');
        if (c) {
            var src = c.contentWindow.document
                    .getElementById('g-recaptcha-response');
            if (src) {
                var target = document.getElementById('g-recaptcha-response');
                target.value = src.value;
            }
        }
        return true;
    }
</script>
</head>
<body>
    <h:form id="g-recaptcha-form">

        <h:panelGroup>
            <iframe id="g-recaptcha-isolator" src="/recaptcha.htm"
                onload='javascript:(function(o){o.style.height=o.contentWindow.document.body.scrollHeight+"px";}(this));'
                style="height: 78px; width: 100%; border: none; overflow: hidden;">
            </iframe>
        </h:panelGroup>

        <textarea id="g-recaptcha-response" name="g-recaptcha-response"
            style="display: none"></textarea>

        <h:panelGroup>

            <h:commandLink onclick="extractRecaptchaResponse()"
                actionListener="#{recaptcha.submit}">
                <span>Submit</span>
            </h:commandLink>

        </h:panelGroup>

    </h:form>
</body>
</html>

recaptcha.htm:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<script src="https://www.google.com/recaptcha/api.js"></script>
</head>
<body>
<div class="g-recaptcha" data-sitekey="xxxxxxx"></div>

and it solves the problem with JSON error, but reCAPTCHA shows popup with image selector and iframe cuts the popup.


Solution

  • If you are using Prototype.js:

    The Prototype JS library overrides the method reduce in the class Array.

    The issue is resolved if you just add the following script after all imports (preferentially after the body tag):

    Array.prototype.reduce = function(callback, initialVal) {
        var accumulator = (initialVal === undefined) ? undefined : initialVal;
        for (var i = 0; i < this.length; i++) {
            if (accumulator !== undefined)
                accumulator = callback.call(undefined, accumulator, this[i], i, this);
            else
                accumulator = this[i];
        }
        return accumulator;
    };