reCAPTCHA JSON中位置0处的意外令牌

问题描述

我们使用reCAPTCHA版本2作为“我不是机器人”复选框。从2020-11-05 19:23:00Z开始在我们的页面加载期间,我们得到了异常:

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)

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

我们的页面未更改。 reCAPTCHA在一瞬间意外中断。在其他页面上,reCAPTCHA仍在工作(可能重要的是,工作页面已嵌入到iframe中)。

有任何提示吗?出了什么问题?

已更新

我们尝试按照@user2384519的建议在JSP页面的iframe中隔离reCAPTCHA:

<%@ 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>

它解决了JSON错误的问题,但是reCAPTCHA会显示带有图片选择器的弹出窗口,而iframe会删除弹出窗口。

解决方法

如果您使用的是Prototype.js:

Prototype JS库重写类reduce中的方法Array

如果您在所有导入之后添加以下脚本(最好在body标签之后),则可以解决此问题:

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;
};

替代解决方案:

解决方案是修改文件Prototype.js并从文件中删除功能reduce

Object.extend(Array.prototype,{
    _each: function(iterator) {
        for (var i = 0,length = this.length; i < length; i++)
            iterator(this[i]);
    },clear: function() {
        this.length = 0;
        return this;
    },first: function() {
        return this[0];
    },last: function() {
        return this[this.length - 1];
    },compact: function() {
        return this.select(function(value) {
            return value != null;
        });
    },flatten: function() {
        return this.inject([],function(array,value) {
            return array.concat(Object.isArray(value) ? value.flatten() : [value]);
        });
    },without: function() {
        var values = $A(arguments);
        return this.select(function(value) {
            return !values.include(value);
        });
    },reverse: function(inline) {
        return (inline !== false ? this : this.toArray())._reverse();
    },//FROM HERE
    reduce: function() {
        return this.length > 1 ? this : this[0];
    },//TO HERE
    uniq: function(sorted) {
        return this.inject([],value,index) {
            if (0 == index || (sorted ? array.last() != value : !array.include(value)))
                array.push(value);
            return array;
        });
    },intersect: function(array) {
        return this.uniq().findAll(function(item) {
            return array.detect(function(value) {
                return item === value
            });
        });
    },clone: function() {
        return [].concat(this);
    },size: function() {
        return this.length;
    },inspect: function() {
        return '[' + this.map(Object.inspect).join(',') + ']';
    },toJSON: function() {
        var results = [];
        this.each(function(object) {
            var value = Object.toJSON(object);
            if (!Object.isUndefined(value)) results.push(value);
        });
        return '[' + results.join(',') + ']';
    }
});

为此,您需要打开jar文件绞盘对RichFaces的引用(richfaces-impl-3.3.3.Final.jar)。

enter image description here

,

我们在11/5上也遇到了同样的问题。为了快速修复,我们在iframe中嵌入了摘要。它被ajax4jsf / framework.pack.js阻塞

,

我们遇到了同样的问题,然后确定该问题是由同一页面上加载的另一个缩小的js文件引起的冲突。

我们将页面上加载的js减少到最低限度,消除了冲突,现在又可以正常工作了。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...