2011-08-28 19 views
25

Estoy tratando de aprovechar el node-request module, pero la documentación no es tan buena. Si realizo una solicitud a un recurso válido y lo canalizo a una secuencia de escritura, todo funciona bien. Sin embargo, si realizo una solicitud a un objeto no válido, la secuencia de escritura aún se crea. Ejemplo, tomemos el siguiente fragmento:Solicitud de nodo: cómo determinar si se produjo un error durante la solicitud.

var x = request("http://localhost:3000/foo.jpg"); 
var st = fs.createWriteStream("foo.jpg"); 
x.pipe(st); 

Si el recurso existe foo.jpg en el servidor, los datos se canaliza a la corriente, y se crea la multa archivo en el servidor. Sin embargo, si foo.jpg no existe en el servidor, aún se crea un archivo contenedor en blanco. No parece haber ningún caso de error o cualquier cosa que se puede aprovechar para determinar si la petición devuelve un 404. He intentado algo como lo siguiente:

var x = request("http://localhost:3000/foo.jpg", function(err, response, body) { 
    if(response.statusCode === 200) { 
     // Success 
     var st = fs.createWriteStream("foo.jpg"); 
     x.pipe(st); 
    } 
}); 

Y también:

request("http://localhost:3000/foo.jpg", function(err, response, body) { 
    if(response.statusCode === 200) { 
     // Success 
     var x = response.request; 
     var st = fs.createWriteStream("foo.jpg"); 
     x.pipe(st); 
    } 
}); 

Para ningún aprovechar. La idea es bastante simple; Solo quiero copiar un archivo identificado por la URL al servidor local. Si la solicitud no es válida (404, etc.), no pipe el archivo; si la solicitud es válida, canalice el archivo. ¿Alguna sugerencia?

+0

Espere, no estoy exactamente seguro de lo que quiere lograr aquí. ¿Qué quieres copiar y cuándo? – Qcom

+6

Por el amor de Dios use ['request'] (https://github.com/mikeal/request) en lugar de node-request. – Raynos

Respuesta

40

escribí petición :)

es posible que desee probar esta solución @Mikeal

var r = request(url) 
r.on('response', function (resp) { 
    resp.headers 
    resp.statusCode 
    r.pipe(new WritableStream()) 
}) 
+1

y ¿cómo volvería a intentar la solicitud si el código de estado fuera 503 y quisiera canalizar la respuesta a la respuesta de su servidor? – naugtur

+0

encontró una manera. revisa mi respuesta. – naugtur

+0

Estoy usando solicitud. Me pregunto cómo obtendrá una devolución de llamada una vez que todo el archivo se haya descargado y guardado en la transmisión. Necesito hacer algo cuando el archivo se descargue. @mikeal – xtu

-5

¿Por qué no utilizar el módulo http directamente? http.request

Tiene un evento de 'error' que puede utilizar para detectar el error.

+9

Porque 'http.request' es una API de bajo nivel en comparación con' request'. Me duele usar – Raynos

+0

Supongo que la http.request nativa puede ser el camino a seguir. – naivedeveloper

5

se ve muy bien, pero puede tener algún problema con la tubería (primeros bytes se puede perder). Hee es un código de actualización:

var r = request(url) 
r.pipe(new WritableStream()); 
r.on('response', function (resp) { 
    resp.headers 
    resp.statusCode 
    // Handle error case and remove your writablestream if need be. 
}) 
+0

Amigo ¡Eres increíble! cerrando el writableStream funcionó. Al no hacerlo, el bloqueo sale del proceso. ¡Salud! – FacePalm

+0

Pero, ¿y si la página devuelve 404 y un cuerpo de respuesta? ¿Eliminar el archivo después de haber sido escrito? –

17

La forma en que terminé tener éxito con las nuevas corrientes en el nodo:

function doQuery(){ 
    var r = request(url) 
    r.pause() 
    r.on('response', function (resp) { 
     if(resp.statusCode === 200){ 
      r.pipe(new WritableStream()) //pipe to where you want it to go 
      r.resume() 
     }else{ } 
    }) 
} 

Esto es muy flexible - si desea volver a intentarlo, puede llamar a la función recursiva con setTimeout

function doQuery(){ 
    var r = request(url) 
    r.pause() 
    r.on('response', function (resp) { 
     if(resp.statusCode === 200){ 
      r.pipe(new WritableStream()) //pipe to where you want it to go 
      r.resume() 
     }else{ 
      setTimeout(doQuery,1000) 
     } 
    }) 
} 
+1

¿Puedes aclarar por qué es necesario detener y reanudar la transmisión en comparación con la respuesta de @ mikeal? –

+0

Creo que es porque quiere pausar la transmisión (no obtener ningún dato) hasta que esté seguro, el recurso en ese servidor sale.Cuando esté seguro de que existe, canalice esa transmisión donde desee y reanude (de hecho, comience) la descarga/transmisión de ese recurso. –

+1

Escribí ese comentario una vez, no tengo idea de qué pasó ... Las transmisiones comienzan a fluir demasiado temprano y bajo carga, obtendrás un archivo que no tiene unos pocos bytes. – naugtur

Cuestiones relacionadas