我对Javascript比较陌生,所以请原谅我。我已经谷歌和测试了一天,没有成功,所以我需要向社区寻求一些帮助。我试图验证我的React JS网站上使用Recaptcha3的联系形式的内容。我根据表单的内容(电子邮件,名称)接收令牌,看起来是正确的,但是将令牌发送到我的后端(Firebase函数)不起作用。我用:
....
2021-08-25T03:45:00.892Z I sendRecaptcha: token undefined
2021-08-25T03:45:01.198Z ? sendRecaptcha: { success: false, error: 'response not valid' }
2021-08-25T03:45:01.199Z ? sendRecaptcha: Unhandled rejection
2021-08-25T03:45:01.246Z ? sendRecaptcha: { success: false, error: 'captcha_error' }
2021-08-25T03:45:01.252056348Z D sendRecaptcha: Function execution took 374 ms, finished with status: 'crash'
我的代码在表单上按下提交后触发云函数sendRecaptcha
:
const handleSubmit = event => {
event.preventDefault()
const apiString = 'https://xxxx.cloudfunctions.net/sendRecaptcha'
setLoading(true);
window.grecaptcha.ready(() => {
window.grecaptcha.execute(SITE_KEY, {action: 'form'})
.then(function(token) {
console.log("TOKEN: ",token);
Axios.get(`${apiString}?token=${token}`)
.then(function (response) {
const score = response.data.score;
console.log("score: ", score);
sendVerifiedContent()
$("#contact").unbind('submit').submit();
})
.catch(function (error) {
console.log("error: ", error);
});
});
});
}
我的index.js云函数(Firebase函数):
const USER_ERROR_CODES = ['missing-input-response', 'invalid-input-response']
exports.sendRecaptcha = functions.https.onRequest(async (req, res) => {
//res.set('Access-Control-Allow-Origin', functions.config().recaptcha.origin);
res.set('Access-Control-Allow-Origin', '*')
res.set('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS')
res.set('Access-Control-Allow-Headers', '*')
const secret = functions.config().recaptacha.key;
functions.logger.log("SECRET:", secret);
const token = res.query.body;
functions.logger.log("token", token);
try {
let result = await axios({
method: 'post',
url: 'https://www.google.com/recaptcha/api/siteverify',
params: {
secret:secret,
response:token,
}
});
let data = result.data || {};
if(!data.success){
throw({
success: false,
error: 'response not valid'
})
}
}catch(err){
console.log(err);
throw err.response ? err.response.data : {success: false, error: 'captcha_error'}
}
})
当window.grecaptcha.execute
函数完成时,我看到令牌,它看起来像这样(看起来OK):
03AGdBq255ghLC0DOUleaz71srZlcYWCiVlR-aldGXQZ6L2D-wIkJb5V_NDh66AYWsERT0w9hFLIt5nVikfjigufJvA2phS_ns-6X8YAza0S-nCS0RUPx1IgJBQUZ1Vl-Cc5AfuOcavSzCicNtSHAcLLXZPY-dY3PbIo-jzelpBelyfD8RGB8dKrWreP2cCfgitjs24xtX8J94ED3WC4DzQKCbfvEEQrEoAHWY2rueU2lDfflBybpz5u7lXccd_zDTORy9WEiHQBK2vEuEuJXZ-85mLP1acI03I1lOXpm_uLBTO3YJMpXc5Jq-4eRO4vDvox23YxfKYgXQd5UZPvkWQWq7sv_9ANUZK1w28LeK7aZO-9KUmGMmm3IFfaOKYrggVAIoEq8ex3unGZTxwq4ZnrYzYhGAx02PAmC5UQEjbBHLDStfYaaLHh8
但是一旦我的云函数被调用,我就无法从req.query.token
获得令牌(functions.logger.log("token", token)
的输出是未定义的),并且函数的其余部分崩溃。
我确定这是一个初学者的问题,但希望得到一些帮助。
更新我遵循了@Dharmaraj的建议,我能够在我的云功能中正确地获得令牌。这个函数似乎卡住了,超时了。我的代码中还有其他需要改进的地方吗?
D sendRecaptcha: Function execution took 60011 ms, finished with status: 'timeout'
query
属性存在于request
对象上,而不存在于response
对象上。要访问查询参数,请将代码重构为:
const token = req.query.token;
// alternatively using object destructuring
const {token} = req.query
req.query
将是所有查询参数的对象。例如,如果您的URL是https://domain.tld?q1=hello&q2=world
,那么req.query
将是{q1: "hello", q2: "world"}
你应该通过发送响应来终止你的HTTP函数,否则它将继续运行60秒(或你的最大超时时间),并最终以超时错误结束:
try {
if (!data.success) {
throw ({
success: false,
error: 'response not valid'
})
}
res.status(200).json({data: data})
} catch (e) {
console.log(e)
res.status(500).json({error: e})
}
从文档中,
确保所有HTTP函数正确终止。通过正确地终止函数,可以避免运行时间过长的函数产生过多的费用。使用res.redirect()、res.send()或res.end()终止HTTP函数。