如何将Node.js的reCAPTCHA验证代码封装为可复用模块并正确调用
问题原因
你封装的checkRecaptcha函数存在变量作用域问题:google_response是在try代码块内部用const声明的,仅在块内可访问,函数最后return google_response时已经超出作用域,所以始终返回undefined。
修正后的可复用模块代码
import fetch from 'node-fetch'; export function fetch_out(url, timeout = 7000) { return Promise.race([ fetch(url, {method: 'POST'}), // 对齐原业务逻辑的POST请求方式 new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout) ) ]); } export async function checkRecaptcha(token, secret_key){ const url = `https://www.google.com/recaptcha/api/siteverify?secret=${secret_key}&response=${token}`; try { const response = await fetch_out(url, 1000); const google_response = await response.json(); // 直接在作用域内返回结果 return google_response; } catch(error) { // 统一返回结构,避免调用端额外判断错误类型 return { success: false, error: error.message }; } }
路由调用示例
方法1:async/await写法(推荐)
给路由处理函数加async修饰符,直接await调用函数即可:
// 按你的实际文件路径引入封装好的模块 import { checkRecaptcha } from './你的模块文件名.js'; app.post('/register_user', async (req, res) => { const secret_key = process.env.RECAPTCHA_SECRET; const token = req.body.recaptcha; const google_response = await checkRecaptcha(token, secret_key); if (google_response.success === true) { res.format({'text/html': () => res.redirect(303, '/register')}) } else { if (google_response.error) { return res.json({ error: google_response.error }); } return res.send({ response: "Failed" }); } })
方法2:Promise .then写法
如果不想修改路由函数为async,也可以用then链调用:
import { checkRecaptcha } from './你的模块文件名.js'; app.post('/register_user', (req, res) => { const secret_key = process.env.RECAPTCHA_SECRET; const token = req.body.recaptcha; checkRecaptcha(token, secret_key) .then(google_response => { if (google_response.success === true) { res.format({'text/html': () => res.redirect(303, '/register')}) } else { if (google_response.error) { return res.json({ error: google_response.error }); } return res.send({ response: "Failed" }); } }) .catch(error => res.json({error})) })
内容的提问来源于stack exchange,提问作者Kaguei Nakueka
相关产品推荐
相关产品推荐

