You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:24:04