node.js - 发送数据流作为响应 - Node.js - 使用 Node.js 的 Azure 文件服务

标签 node.js azure azure-storage azure-mobile-services node.js-stream

我正在使用 node.js 为 Azure 文件存储创建文件服务。我为此使用azure-storage-node (http://azure.github.io/azure-storage-node/)。

我正在尝试从 Azure 文件存储下载文件。下面是我的代码片段

// Download a file from Share
exports.get = function(request, response){
    var shareName = request.headers.sharename;
    var dirPath = request.headers.directorypath;
    var fileName = request.headers.filename;

    var fileService = azure.createFileService();

    var readStream = fileService.createReadStream(shareName, dirPath, fileName);

    var dataLength = 0;
    var body = '';
    readStream.on('data', function (chunk) {
    dataLength += chunk.length;
  })

    readStream.on('end', function(){
      console.log('The length was:', dataLength);
    });

    response.setHeader('Content-Type', 'application/json');
    response.send(statusCodes.OK, JSON.stringify("Success!"));

}

我能够获取数据流。但是我如何在响应中发送流,以便我们可以在其余调用中获取它。

我尝试了readStream.pipe(response);

response.write(typeof chunk);
response.end() but it doesnt work; 

我是 Node.js 新手。请帮我解决这个问题。

更新:

我尝试了以下方法。

response.writeHead(200, {'Content-Type': 'application/json'});

var readStream = fileService.createReadStream(shareName, dirPath, fileName);
readStream.pipe(response);

但它抛出以下错误。

    ERROR
An unhandled exception occurred. Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:679:11)
    at ServerResponse.res.setHeader (D:\home\site\wwwroot\node_modules\express\node_modules\connect\lib\patch.js:59:22)
    at ServerResponse.res.set.res.header (D:\home\site\wwwroot\node_modules\express\lib\response.js:518:10)
    at addDefaultHeaders (D:\home\site\wwwroot\runtime\request\requesthandler.js:582:9)
    at ServerResponse.<anonymous> (D:\home\site\wwwroot\runtime\request\requesthandler.js:291:13)
    at ServerResponse._.wrap [as end] (D:\home\site\wwwroot\node_modules\underscore\underscore.js:692:22)
    at ChunkStream.onend (stream.js:66:10)
    at ChunkStream.EventEmitter.emit (events.js:126:20)
    at ChunkStream.end (D:\home\site\wwwroot\App_Data\config\scripts\node_modules\azure-storage\lib\common\streams\chunkstream.js:90:8)
    at Request.onend (stream.js:66:10)

fileService.createReadStream(shareName, dirPath, fileName);的返回数据类型为ChunkStream

更新:

这是我更新后的代码,可以运行。

    var option = new Object();
    option.disableContentMD5Validation = true;
    option.maximumExecutionTimeInMs = 20 * 60000;
    option.timeoutIntervalInMs = 20 * 6000;

    fileService.getFileToStream(shareName, dirPath, fileName, response, option, function(error, result, res) {
        if(!error) {
            if(res.isSuccessful) {
                console.log(result);
        console.log(res);
        console.log("Success!");
      }
        }
    });

但更常见的是我遇到以下错误。

ERROR
An unhandled exception occurred. Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:679:11)
at ServerResponse.res.setHeader (D:\home\site\wwwroot\node_modules\express\node_modules\connect\lib\patch.js:59:22)
at ServerResponse.res.set.res.header (D:\home\site\wwwroot\node_modules\express\lib\response.js:518:10)
at addDefaultHeaders (D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\request\requesthandler.js:590:9)
at ServerResponse. (D:\home\site\wwwroot\node_modules\azure-mobile-services\runtime\request\requesthandler.js:299:13)
at ServerResponse._.wrap as end
at Request.onend (stream.js:66:10)
at Request.EventEmitter.emit (events.js:126:20)
at IncomingMessage.Request.onRequestResponse.strings (D:\home\site\wwwroot\App_Data\config\scripts\node_modules\azure-storage\node_modules\request\request.js:1153:12)
at IncomingMessage.EventEmitter.emit (events.js:126:20)

最佳答案

NodeJS类http.ServerResponse实现了Writable Stream接口(interface),请引用NodeJS API https://nodejs.org/api/http.html#http_class_http_serverresponsehttps://nodejs.org/api/stream.html#stream_class_stream_writable_1 .

因此,您只需要在示例代码“getFileToStream” http://azure.github.io/azure-storage-node/#toc8 中使用对象 response 而不是流写入器 fs.createStreamWriter(...)当您将数据流发送到 NodeJS 的响应时。

这是我的示例代码,如下所示:

var http = require('http');
var azure = require('azure-storage');
var fileService = azure.createFileService('<storage_key_name>','<storage_access_key>');

http.createServer(function (request, response) {
    var shareName = request.headers.sharename;
    var dirPath = request.headers.directorypath;
    var fileName = request.headers.filename;
    response.setHeader('Content-Type', 'application/json');
    fileService.getFileToStream(shareName, dirPath, fileName, response, {disableContentMD5Validation: true}, function(error, result, response) {
            if(!error) {
                    //console.log(result);
                    //console.log(response);
                   if(response.isSuccessful) {
                                console.log("Success!");
                   }
            }
    });
}).listen(1337, "127.0.0.1");

console.log('Server running at http://127.0.0.1:1337/');

最诚挚的问候。


要从 Azure 文件存储获取大于 4MB 的文件,有一个请求 header x-ms-range-get-content-md5,它将导致状态代码 400 code>(Bad Request) 错误,请参阅 Azure 文件存储的获取文件 REST API 文档 https://msdn.microsoft.com/en-us/library/azure/dn194274.aspx ,见下文:

enter image description here

因此,我查看了适用于 Node 的 Azure 文件存储 SDK 的源代码 ( https://github.com/Azure/azure-storage-node/blob/master/lib/services/file/fileservice.js )。对于getFileToTextgetFileToLocalFilecreateReadStreamgetFileToStream函数,您需要设置options.disableContentMD5Validation 属性来避免错误,请参见下文。

  • @param {boolean} [options.disableContentMD5Validation] When set to true, MD5 validation will be disabled when downloading files.

并引用getFileToStream的源码为例:

enter image description here

在我的示例代码中,需要在调用函数 getFileToStream 的前面添加代码 {disableContentMD5Validation: true} 作为选项。

关于node.js - 发送数据流作为响应 - Node.js - 使用 Node.js 的 Azure 文件服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33215170/

相关文章:

javascript - 无法读取未定义的属性 'isLoggedIn'

.net - 我如何知道我的 Azure 表存储帐户名称?

azure - 我可以在同一个 Azure 容器上创建和添加多少个访问策略?

azure - 复制到雪花保存文件作为八位字节流,

mongodb - node.js + mongodb 应用程序的基本架构是什么?

json - Node 流,将数组包装为对象

node.js - 请求 : How to set user agent for every request?

azure - 从 Azure HDInsights 中的分区 parquet 文件创建 Hive 外部表

sql-server - 我需要在 Azure 的 IIS 中托管 Web 应用程序,该怎么做?

azure - 如何允许非管理员用户在 Azure SQL 数据库上使用 BULK INSERT