【问题标题】:What is the output of a piped file stream?管道文件流的输出是什么?
【发布时间】:2017-08-02 21:58:03
【问题描述】:

也许这个问题的措辞不是最好的,但这里有更多的上下文。使用 GridFSBucket,我可以在 mongo 中存储一个文件并获得该文件的下载流。这是我的问题。假设我想将该文件作为对我的 http 请求的响应发回。

我愿意:

downloadStream.pipe(res);

现在,当我在客户端打印 responseText 时,我得到了一些带有一些看起来被加密的时髦字符的长字符串。这个字符串/流的格式/类型是什么?如何设置我的响应,以便在客户端获取流数据作为 ArrayBuffer?

谢谢

更新:

我还没有解决这个问题,但是@Jekrb 的建议给出了与console.log(this.responseText) 完全相同的输出。看起来字符串不是缓冲区。以下是这两行的输出:

console.log(this.responseText.toString('utf8'))

var byteArray = new Uint8Array(arrayBuffer);

更新 2 - 代码片段

前端:

    var savePDF = function(blob){
      //fs.writeFile("test.pdf",blob);
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (this.readyState === XMLHttpRequest.DONE && this.status === 200){

            //TO DO: Handle the file in the response which we will be displayed.
            console.log(this.responseText.toString('utf8'));
            var arrayBuffer = this.responseText;
            if (arrayBuffer) {
              var byteArray = new Uint8Array(arrayBuffer);
            }
            console.log(arrayBuffer);

          }
      };
      xhr.open("POST","/pdf",true);
      xhr.responseType = 'arrayBuffer';
      xhr.send(blob);

    };

后端:

app.post('/pdf',function(req,res){

  MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
  if(err) return console.dir(err);
  console.log("Connected to Database");

  var bucket = new GridFSBucket(db, { bucketName: 'pdfs' });
  var CHUNKS_COLL = 'pdfs.chunks';
  var FILES_COLL = 'pdfs.files';
  // insert file
  var uploadStream = bucket.openUploadStream('test.pdf');
  var id = uploadStream.id;

  uploadStream.once('finish', function() {

     console.log("upload finished!")

     var downloadStream = bucket.openDownloadStream(id);
     downloadStream.pipe(res);
  });

  // This pipes the POST data to the file
  req.pipe(uploadStream);
});
});

【问题讨论】:

  • 如果要下载pdf,则需要进行如下设置。 Content-Type:application/octet-stream Content-Disposition:附件;文件名="file.pdf"

标签: javascript ajax node.js mongodb express


【解决方案1】:

我的猜测是响应被输出为未经过 base64 编码(仍然是缓冲区)的普通二进制文件,或者是需要先解压缩的压缩 (gzip) 响应。

虽然没有看到代码,但很难查明问题。

更新:

看起来您缺少正确的响应标头。

尝试在downloadStream.pipe(res): 之前设置这些标头:

res.setHeader('Content-disposition', 'attachment; filename=test.pdf');
res.set('Content-Type', 'application/pdf');

【讨论】:

  • 我在上面的原始问题中发布了更多信息。
  • Kerami 我用我正在使用的代码编辑了我的原始帖子。
  • 我在 console.log 响应文本时得到相同的输出。我想设置标题没有帮助。
  • @ribarcheto94 我不确定您期望的输出是什么,但您正在上传一个 pdf 文件,然后尝试将其作为流下载。您得到的输出是 PDF 文件的二进制数据。 console.log 没有多大意义,因为它只会向您显示胡言乱语。您可以做的是通过设置正确的标题来下载文件。
  • 感谢您的意见,它确实让我朝着正确的方向前进。现在我有另一个我以前没有真正考虑过的问题,那就是在服务器上获取文件名。由于我只是将数据从请求传输到上传流,因此我无权访问我正在发送的数据。我也没有办法通过我的 POST 发送文件名,因为我只是发送 blob。有办法解决吗?
【解决方案2】:

您的流可能已经是一个缓冲区。您或许可以调用responseText.toString('utf8') 将流式数据转换为可读字符串。

【讨论】:

  • 感谢您的上述建议,但没有破译文本。检查上面我的第二个答案中的输出。如果您有其他想法,请告诉我。谢谢
【解决方案3】:

我解决了!!!

在发出请求之前,基本上将响应类型预设为“arraybuffer” req.responseType = "arraybuffer"

现在,收到回复后,不要使用responseText,而是使用responseresponse 包含带有文件数据的数组缓冲区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 2015-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-02-16
    • 2010-12-23
    相关资源
    最近更新 更多