节点请求 - 如何确定请求期间是否发生错误?

nai*_*per 31 node.js

我正在尝试利用节点请求模块,但文档并不是那么好.如果我向有效资源发出请求并将其传递给Writable Stream,那么一切正常.但是,如果我向无效对象发出请求,则仍会创建可写流.例如,请使用以下代码段:

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

如果服务器上存在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);
    }
});
Run Code Online (Sandbox Code Playgroud)

并且:

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);
    }
});
Run Code Online (Sandbox Code Playgroud)

无济于事.这个想法非常简单; 我只想将URL标识的文件复制到本地服务器.如果请求无效(404等),请不要管道文件; 如果请求有效,则管道文件.有什么建议?

mik*_*eal 44

我写了请求:)

你可能想试试这个

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


nau*_*tur 22

我最终在节点中成功使用新Streams的方式:

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{  }
    })
}
Run Code Online (Sandbox Code Playgroud)

这非常灵活 - 如果要重试,可以递归调用该函数 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)
       }
    })
}
Run Code Online (Sandbox Code Playgroud)


Nea*_*mar 5

@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.
})
Run Code Online (Sandbox Code Playgroud)