【问题标题】:Node-request - How to determine if an error occurred during the request?节点请求 - 如何确定请求期间是否发生错误?
【发布时间】:2011-11-05 14:00:16
【问题描述】:

我正在尝试利用node-request module,但文档不是那么好。如果我向有效资源发出请求并将其通过管道传输到可写流,则一切正常。但是,如果我向无效对象发出请求,仍会创建可写流。例如,取下面的sn-p:

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 等),请不要通过管道传输文件;如果请求有效,则通过管道传输文件。有什么建议吗?

【问题讨论】:

  • 等等,我不确定你想在这里完成什么。您要复制什么内容以及何时复制?
  • 看在上帝的份上,请使用request 而不是节点请求。

标签: node.js


【解决方案1】:

我写了请求:)

你可能想试试这个

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

【讨论】:

  • 如果状态码是 503 并且您想通过管道将响应发送到服务器的响应,您将如何重试请求?
  • 找到了方法。检查我的答案。
  • 我正在使用请求。我想知道在文件全部下载并保存到流后如何获得回调?下载文件时我需要做一些事情。 @mikeal
【解决方案2】:

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

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

【讨论】:

  • 与@mikeal 的回答相比,您能否说明为什么需要暂停和恢复流?
  • 我认为这是因为您想暂停流(不获取任何数据),直到您确定该服务器上的资源退出。当您确定它存在时,将该流传输到您想要的任何位置并继续(实际上开始)下载/流式传输该资源。
【解决方案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.
})

【讨论】:

  • 哥们,你太棒了!关闭 writableStream 有效。不这样做崩溃退出该过程。干杯!
  • 但是如果页面返回 404 和响应正文怎么办?文件写入后删除?
【解决方案4】:

为什么不直接使用http模块。http.request

它有一个“错误”事件,您可以使用它来捕获错误。

【讨论】:

  • 因为与request 相比,http.request 是一个低级 API。使用起来很痛苦
  • 我想本地 http.request 可能是要走的路。
猜你喜欢
  • 2019-07-17
  • 2018-06-04
  • 1970-01-01
  • 1970-01-01
  • 2017-06-29
  • 2016-05-09
  • 2021-01-14
  • 2021-01-05
  • 1970-01-01
相关资源
最近更新 更多