我一直在努力将Google Recaptcha集成到Meteor和AngularJS Web应用程序中。在我不得不验证Recaptcha响应之前,一切都进行得很顺利-出于某些奇怪的原因,我无法从后端到前端得到异步响应。

我尝试了很多不同的变体,并且总体上在SO和Internet上阅读了很多很多文章,但是没有运气-所以我选择发表自己的问题。



这是我在做什么:

客户:

Meteor.call('recaptcha.methods.validateRecaptcha', { 'response' : this.recaptcha.getResponse(this.id) }, function(error, result) {
    // error and result are both undefined
    console.log('Do something with the ' + error + ' or ' + result + '.');
}


因此,我正在调用Meteor方法,并传递一个在该方法完成时运行的回调。但是,errorresult参数均未定义。

服务器:

run: function(data) {
    if (this.isSimulation) {
        /*
         * Client-side simulations won't have access to any of the
         * Meteor.settings.private variables, so we should just stop here.
         */
        return;
    }

    return Meteor.wrapAsync(HTTP.post)(_someUrl, _someOptions);
}


最后一行是我在几份流星指南中找到的同步/异步结构的简化版本(我也尝试过此版本),即:

var syncFunc = Meteor.wrapAsync(HTTP.post);
var result = syncFunc(Meteor.settings.private.grecaptcha.verifyUrl, _options);
return result;


我也尝试使用Futures版本:

var Future = Npm.require( 'fibers/future' );
var future = new Future();
var callback = future.resolver();
HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options, callback);

return future.wait();




现在,这里的意图是我使用Meteor.call()从客户端调用此方法,客户端存根运行(以防止模拟错误,因为我们在真实的非SO服务器端代码中使用私有Meteor.settings变量)并立即返回(发生),并且服务器在将结果返回给客户端之前不会触发Google的Recaptcha API(发生并且服务器收到响应)(不会发生-发生回调但没有错误/成功数据) )。

我认为正在发生以下两种情况之一:


我只是在做错事,而且没有正确地将数据发送回客户端。
同步客户端存根(立即返回)告诉客户端服务器响应并不重要,因此它从不等待适当的异步响应。


任何流星大师都可以在这里称重,让我知道发生了什么事以及如何获取异步请求以在Meteor应用程序中正常播放吗?

谢谢!

最佳答案

HTTP.call的通用版本HTTP.postdocumentation中,它表示


  可选的回调。如果传递,该方法将异步运行,而不是同步运行,并调用asyncCallback。在客户端上,此回调是必需的。


因此,在服务器上,您可以像这样异步运行它

run: function(data) {
    if (this.isSimulation) {
        /*
         * Client-side simulations won't have access to any of the
         * Meteor.settings.private variables, so we should just stop here.
         */
        return;
    }

    // No need to pass callback on server.
    // Since this part is not executed on client, you can do this
    // Or you can use Meteor.isClient to run it asynchronously when the call is from client.
    return HTTP.post(Meteor.settings.private.grecaptcha.verifyUrl, _options);
}

09-25 17:18
查看更多