Node -request - Как определить, произошла ли ошибка во время запроса?

Я пытаюсь использовать node -request модуль, но документация не так уж полезна. Если я сделаю запрос к действительному ресурсу и передам его в Writable Stream, все будет хорошо. Однако, если я делаю запрос к недопустимому объекту, Writable Stream по-прежнему создается. Например, возьмите следующий фрагмент:

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

Если ресурс foo.jpg существует на сервере, данные передаются по потоку в поток, и он создает файл на сервере. Однако, если на сервере существует foo.jpg не, пустой файл контейнера по-прежнему создается. Кажется, что нет события ошибки или чего-либо, что можно использовать, чтобы определить, вернул ли запрос 404. Я пробовал что-то вроде следующего:

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

А также:

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

Безрезультатно. Идея довольно проста; Я просто хочу скопировать файл, идентифицированный URL-адресом, на локальный сервер. Если запрос недействителен (404 и т.д.), Не перетаскивайте файл; если запрос действителен, подключите файл. Любые предложения?

Ответ 1

я написал запрос:)

вы можете попробовать это

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

Ответ 2

Как я закончил с новыми потоками в node:

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

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

Ответ 3

@Решение Mikeal выглядит великолепно, но может иметь некоторые проблемы с трубопроводом (первые несколько байтов могут быть пропущены). Привет, обновленный код:

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

Ответ 4

Почему бы не использовать http-модуль напрямую. http.request

У этого есть событие ошибки, которое вы можете использовать, чтобы поймать ошибку.