javascript - react - El servidor se bloquea en HTTP.call con Meteor+resultados asíncronos no coincidentes
meteor react (2)
Su solicitud de API recibe una respuesta de desafío 401 no autorizada.
Es posible que necesite proxy su solicitud para evitar el desafío.
Obtuve dos resultados muy extraños tratando de hacer algunas llamadas GET básicas con la biblioteca HTTP de Meteor.
Estas mismas solicitudes funcionan bien con Curl y Python, por lo que no están del lado de la API.
1. El resultado no es coherente con el resultado de la devolución de llamada asíncrona
Estoy usando el siguiente código en mis métodos de meteoritos:
//snip! Meteor methods continued above.
getEmails: function(authId, threadId){
result = HTTP.get("https://api.nylas.com/threads", {auth:authId}, function(error, result){
console.log(result);
});
return result
}
Usando las herramientas de desarrollador de Chrome, puedo examinar el objeto devuelto.
Object {statusCode: 401, content: "{↵ "message": "Could not verify access credential.",↵ "type": "invalid_request_error"↵}", headers: Object, data: Object}content: "{↵ "message": "Could not verify access credential.",↵ "type": "invalid_request_error"↵}"data: Objectheaders: ObjectstatusCode: 401__proto__: Object
Ahora esta es la parte extraña: fíjate que también tengo un console.log en la devolución de llamada asíncrona. ¡Esa salida en el servidor realmente devuelve los datos que esperaría recibir de una llamada API correcta!
Es un poco largo y personal para publicar, pero devuelve un estado 200.
2. Usar params en la llamada bloquea mi servidor
Esta es una copia del código anterior con un cambio muy leve (incluidas las opciones de parámetros).
//snip! Meteor methods continued above.
getEmails: function(authId, threadId){
result = HTTP.get("https://api.nylas.com/threads", {params:{id:threadId}}, {auth:authId}, function(error, result){
console.log(result);
});
return result
}
Hacer este cambio bloquea por completo el servidor Meteor cada vez que llamo a este método.
Esto es lo que está impreso en las herramientas de desarrollo de Chrome:
Exception while simulating the effect of invoking ''getEmails'' Error: Can''t make a blocking HTTP call from the client; callback required.(…) Error: Can''t make a blocking HTTP call from the client; callback required.
Y esto es lo que estoy viendo en el servidor:
TypeError: object is not a function
W20151110-20:52:42.024(-8)? (STDERR) at packages/http/httpcall_server.js:74:1
W20151110-20:52:42.024(-8)? (STDERR) at packages/underscore/underscore.js:750:1
W20151110-20:52:42.025(-8)? (STDERR) at Request._callback (packages/http/httpcall_server.js:116:1)
W20151110-20:52:42.025(-8)? (STDERR) at Request.self.callback (/Users/max/.meteor/packages/http/.1.1.1.murctg++os+web.browser+web.cordova/npm/node_modules/request/request.js:344:22)
W20151110-20:52:42.025(-8)? (STDERR) at Request.emit (events.js:98:17)
W20151110-20:52:42.025(-8)? (STDERR) at Request.<anonymous> (/Users/max/.meteor/packages/http/.1.1.1.murctg++os+web.browser+web.cordova/npm/node_modules/request/request.js:1239:14)
W20151110-20:52:42.026(-8)? (STDERR) at Request.emit (events.js:117:20)
W20151110-20:52:42.026(-8)? (STDERR) at IncomingMessage.<anonymous> (/Users/max/.meteor/packages/http/.1.1.1.murctg++os+web.browser+web.cordova/npm/node_modules/request/request.js:1187:12)
W20151110-20:52:42.027(-8)? (STDERR) at IncomingMessage.emit (events.js:117:20)
W20151110-20:52:42.027(-8)? (STDERR) at _stream_readable.js:944:16
Todo esto parece muy básico, así que me sorprende que no esté funcionando.
¿Qué me estoy perdiendo que está causando todos estos problemas?
Confundir sincronización y asincronización (particularmente con HTTP
) es un error muy común con el meteorito. Aquí está la regla: si desea recuperar el resultado del método, use una llamada síncrona. Consulte esta sección de los documentos para ver un ejemplo. Su implementación debería verse algo así como:
Meteor.methods({
getEmails: function (authId, threadId) {
check(authId, String);
check(threadId, String);
try {
// note that options is a single object
var options = {auth: authId, params: {id:threadId};
var result = HTTP.get("https://api.nylas.com/threads", options);
// this is just a guess - you should log the result to find
// out what parts you need to extract
return result.data;
} catch (e) {
// something bad happened
return false;
}
}});
En el cliente, harás algo como esto:
Meteor.call(''getEmails'', authId, threadId, function(err, result) {
return console.log(result);
});
Nota:
-
options
deben ser un solo argumento.HTTP.get
pasando dos valores por opciones, pero los métodosHTTP.get
que el tercer argumento es una devolución de llamada. En su caso, era un objeto y, por lo tanto, los errores. - De acuerdo con el meteo docs auth no pertenece a params, por lo que es lo que está causando el error 401 en su Autenticación HTTP básica.
- Esta implementación solo funciona en el servidor, así que colóquela en su directorio de
server
o envuélvala en un bloque isServer .