【问题标题】:Node: Downloading a zip through Request, Zip being corrupted节点:通过请求下载 zip,Zip 已损坏
【发布时间】:2012-08-19 19:56:34
【问题描述】:

我正在使用出色的 Request 库在 Node 中下载文件,这是我正在开发的一个小型命令行工具。 Request 非常适合拉入单个文件,完全没有问题,但它不适用于 ZIP。

例如,我正在尝试下载Twitter Bootstrap 存档,该存档位于以下网址:

http://twitter.github.com/bootstrap/assets/bootstrap.zip

代码的相关部分是:

var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
var output = "bootstrap.zip";
request(fileUrl, function(err, resp, body) {
  if(err) throw err;
  fs.writeFile(output, body, function(err) {
    console.log("file written!");
  }
}

我也尝试将编码设置为“二进制”,但没有成功。实际的 zip 约为 74KB,但通过上述代码下载时约为 134KB,在 Finder 中双击解压时,出现错误:

无法将“bootstrap”提取到“nodetest”(错误 21 - 是目录)

我感觉这是一个编码问题,但不知道从哪里开始。

【问题讨论】:

    标签: javascript node.js


    【解决方案1】:

    是的,问题在于编码。当您等待整个传输完成时,body 默认强制转换为字符串。您可以告诉request 给您一个Buffer,而不是将encoding 选项设置为null

    var fileUrl = "http://twitter.github.com/bootstrap/assets/bootstrap.zip";
    var output = "bootstrap.zip";
    request({url: fileUrl, encoding: null}, function(err, resp, body) {
      if(err) throw err;
      fs.writeFile(output, body, function(err) {
        console.log("file written!");
      });
    });
    

    另一个更优雅的解决方案是使用pipe() 将响应指向文件可写流:

    request('http://twitter.github.com/bootstrap/assets/bootstrap.zip')
      .pipe(fs.createWriteStream('bootstrap.zip'))
      .on('close', function () {
        console.log('File written!');
      });
    

    一个班轮总是赢:)

    pipe() 返回目标流(在本例中为 WriteStream),因此您可以监听其close 事件以在文件写入时收到通知。

    【讨论】:

    • 太好了,谢谢!第一个代码被阻塞了:)第二种方法更好,但我需要一种方法来在文件写入后运行回调,这就是我选择第一种选择的原因。
    • 通过在WriteStream上监听close事件,仍然可以在第二个选项写入文件时得到回调:request(fileUrl).pipe(fs.createWriteStream(output)).on('close', function () {console.log('File written!');});
    • 这样好多了!非常感谢:)
    • request 文档中。它说“如果为空,则正文作为缓冲区返回。” npmjs.com/package/request
    • {encoding: null} 结束了 10 个小时的调试。谢谢,这需要在谷歌搜索中排名
    【解决方案2】:

    我正在搜索一个请求 zip 并在我的服务器中不创建任何文件的情况下提取它的函数,这是我的 TypeScript 函数,它使用 JSZIP moduleRequest

    let bufs : any = [];
    let buf : Uint8Array;
    request
        .get(url)
        .on('end', () => {
            buf = Buffer.concat(bufs);
    
            JSZip.loadAsync(buf).then((zip) => {
                // zip.files contains a list of file
                // chheck JSZip documentation
                // Example of getting a text file : zip.file("bla.txt").async("text").then....
            }).catch((error) => {
                console.log(error);
            });
        })
        .on('error', (error) => {
            console.log(error);
        })
        .on('data', (d) => {
            bufs.push(d);
        })
    

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2014-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多