如何在Angular中读取Node.js流?

6

在Node.js中,我可以像这样向客户端发送流:

DockerService.get().pull('my/image', function(err, stream) {
  if (err) {
    return res.badRequest(err);
  } else {
    return stream.pipe(res);
  }
});

这是由一个使用$http.get的AngularJS客户端触发的。
pull: function() {
  var url = ENV.apiEndpoint + '/docker/pull';
  var promise = $http.get(url).success(function(response) {
    return response;
  }).error(function(data, status) {

  });
  return promise;
}

然而我无法读取该流。从 Angular 中,我收到了一个错误消息:
SyntaxError: Unexpected token {
    at Object.parse (native)
    at fromJson (file://build/vendor/angular/angular.js:1065:14)
    at defaultHttpResponseTransform (file://build/vendor/angular/angular.js:8579:16)
    at file://build/vendor/angular/angular.js:8664:12
    at forEach (file://build/vendor/angular/angular.js:323:20)
    at transformData (file://build/vendor/angular/angular.js:8663:3)
    at transformResponse (file://build/vendor/angular/angular.js:9389:23)
    at processQueue (file://build/vendor/angular/angular.js:13189:27)
    at file://build/vendor/angular/angular.js:13205:27
    at Scope.$get.Scope.$eval (file://build/vendor/angular/angular.js:14401:28)

我找不到有关如何在Angular中处理流的信息。你能帮我吗? 标头: enter image description here 响应内容太大,无法在此处呈现,因此这里是其第一部分: enter image description here 预览: enter image description here

你能展示一下你的服务器代码返回的HTTP头和正文吗?我猜测你的'Content-Type'头部与应用程序/json不匹配,但是从badRequest(err)返回了一个纯文本消息正文。 - Peter Lyons
@PeterLyons,GET请求本身返回200 OK。在Chrome的网络选项卡中,我可以看到已传输的响应。但是在Angular中,会触发错误回调。响应类型为JSON。根本没有调用badRequest。 - DarkLeafyGreen
请看这里,如果您想了解如何使用AngularJS处理Node.js流:http://stackoverflow.com/questions/26300350/handling-nodejs-streams-with-angularjs - Zeeshan Hassan Memon
你能展示一下你的服务器代码正在运行的HTTP头和正文吗?这样我/我们或许可以帮助你。在你的问题中放置代码片段和原始的HTTP数据,而不是英语描述。然后我们就可以进行故障排除了。很明显响应正文不是有效的JSON格式,所以我们需要排查这是否是分块编码问题或其他问题。 - Peter Lyons
@PeterLyons 好的,我已经更新了我的问题,加上了头部和响应。 - DarkLeafyGreen
2个回答

4

所以这不是有效的JSON,而是一系列以换行符分隔的(可能是)JSON消息。这就是"unexpected token '{'"的意思。Angular内置的解析器不支持此功能。问题实际上与流式数据和缓冲数据无关,只是angularjs不直接支持的主体格式。您需要确保绕过Angular内置的解析器,然后可以在换行符上拆分字符串,并尝试/捕获将每行解析为JSON对象。

据我所知,最适合流式传输到浏览器的模块是oboe.js。您可以使用RonB/angular-oboe结合一些代码来缓冲每行,然后将ndjson语法解析为JS对象流。


1

try to add:

res.attachment()

或者

res.writeHead(200, {'Content-Type': data.ContentType });

也许问题就在那里...

在你的代码中,它看起来应该是这样的:

DockerService.get().pull('my/image', function(err, stream) {
  if (err) {
    return res.badRequest(err);
  } else {
    res.attachment('your_file.jpg'); // add file name here like req.files.name
    return stream.pipe(res);
  }
});

或者

DockerService.get().pull('my/image', function(err, stream) {
  if (err) {
    return res.badRequest(err);
  } else {
    res.writeHead(200, {'Content-Type': data.ContentType }); //switch data.ContentType to yours or get it from the file
    return stream.pipe(res);
  }
});

有时使用res.attachment是个好主意,因为它使用正确的头部信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接