简体   繁体   English

Meteor 方法向客户端返回未定义(异步)

[英]Meteor method returns undefined to the client (asynchronous)

I've been working on integrating Google Recaptcha into a Meteor and AngularJS web application.我一直致力于将 Google Recaptcha 集成到 Meteor 和 AngularJS Web 应用程序中。 Everything was smooth sailing until I had to validate the recaptcha response -- for some bizarre reason, I can't get an async response from the backend to the frontend.一切都很顺利,直到我不得不验证 recaptcha 响应——出于某种奇怪的原因,我无法从后端到前端获得异步响应。

I've tried a lot of different variations and have read many, many posts on SO and the internet in general, but with no luck -- so I opted to post my own question.我已经尝试了很多不同的变体,并在 SO 和互联网上阅读了很多很多帖子,但没有运气——所以我选择发布我自己的问题。


Here's what I'm doing:这是我在做什么:

Client:客户:

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 + '.');
}

So, I'm calling a Meteor method and passing in a callback that is run when the method is done.因此,我正在调用 Meteor 方法并传入在该方法完成时运行的回调。 However, the error and result parameters are both undefined.但是, errorresult参数都是未定义的。

Server:服务器:

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

That last line is a shortened version of the sync/async structure that I've found in several Meteor guides (I also tried this version), namely:最后一行是我在几个 Meteor 指南中找到的同步/异步结构的缩短版本(我也尝试过这个版本),即:

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

I've also tried a version using Futures:我也试过一个使用 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();

Now, the intention here is that I use Meteor.call() to call this method from the client, the client-side stub runs (to prevent simulation errors since we use private Meteor.settings variables in the real non-SO server-side code) and returns immediately (which happens), and the server hits Google's Recaptcha API (which happens and the server receives a response) before returning the result to the client (which doesn't happen -- the callback occurs but with no error/success data).现在,这里的意图是我使用Meteor.call()从客户端调用此方法,客户端存根运行(以防止模拟错误,因为我们在真正的非 SO 服务器端使用私有Meteor.settings变量代码)并立即返回(发生这种情况),并且服务器在将结果返回给客户端(这不会发生——回调发生但没有错误/成功数据)。

My thought is that one of two things are happening:我的想法是正在发生两件事之一:

  1. I'm just doing something wrong and I'm not properly sending the data back to the client.我只是做错了什么,我没有正确地将数据发送回客户端。
  2. The synchronous client stub (which returns immediately) is telling the client that the server response isn't important, so it never waits for the proper asynchronous response.同步客户端存根(立即返回)告诉客户端服务器响应并不重要,因此它从不等待正确的异步响应。

Could any of the Meteor gurus weigh in here and let me know what's going on and how to get async requests to play nicely in a Meteor application?任何 Meteor 大师都可以在这里权衡一下,让我知道发生了什么以及如何让异步请求在 Meteor 应用程序中很好地发挥作用?

Thanks!谢谢!

From the documentation for HTTP.call , which is the generic version of HTTP.post , it says文档HTTP.call ,这是通用版HTTP.post ,它说

Optional callback.可选回调。 If passed, the method runs asynchronously, instead of synchronously, and calls asyncCallback.如果通过,该方法将异步运行,而不是同步运行,并调用 asyncCallback。 On the client, this callback is required.在客户端,此回调是必需的。

So, on server, you can run it asynchronously like this因此,在服务器上,您可以像这样异步运行它

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM