问题描述
我的问题与这非常相似一个,其中描述了如何使用Iron Router提供本地文件.我需要做同样的事情,但不是从磁盘同步读取文件,而是需要从S3获取文件,这是一个异步调用.
My question is very similar to this one which describes how to serve a local file using Iron Router. I need to do the same, but instead of reading the file synchronously from disk, I need to get the file from S3 which is an asynchronous call.
问题似乎是在异步s3.getObject
完成之前返回了action
方法,给了我以下错误.
The problem appears to be the fact that the action
method has returned before the asynchronous s3.getObject
completes giving me the following error.
Error: Can't render headers after they are sent to the client.
我假设Iron Router在意识到我尚未处理我的action
方法中的响应时,正在为我生成响应,但是我很困惑如何告诉它等待我的异步调用完成.
I'm assuming that Iron Router is generating the response for me when it realizes that I haven't handled the response in my action
method, but I'm stumped about how to tell it to wait for my asynchronous call to finish.
这是我的代码.
Router.map(function () {
this.route('resumeDownload', {
where: 'server',
path: '/resume/:_id',
action: function () {
var response = this.response;
var candidate = Candidates.findOne(this.params._id);
if (!candidate || !candidate.resumeS3Key) {
// this works fine because the method hasn't returned yet.
response.writeHead(404);
return response.end();
}
var s3 = new AWS.S3();
s3.getObject({Bucket: 'myBucket', Key: candidate.resumeS3Key}, function (err, data) {
if (err) {
// this will cause the error to be displayed
response.writeHead(500);
return response.end();
}
// this will also cause the error to be displayed
response.writeHead(200, {'Content-Type': data.ContentType});
response.end(data.Body);
});
}
});
});
推荐答案
我自己解决了这个问题.我需要在action
方法中使用future
.
I was able to solve this one myself. I needed to use a future
in my action
method.
这是工作代码.
Router.map(function () {
this.route('resumeDownload', {
where: 'server',
path: '/resume/:_id',
action: function () {
var response = this.response,
candidate = Candidates.findOne(this.params._id);
if (!candidate || !candidate.resumeS3Key) {
response.writeHead(404);
return response.end();
}
var Future = Npm.require('fibers/future'),
s3 = new AWS.S3(),
futureGetObject = Future.wrap(s3.getObject.bind(s3)),
data = futureGetObject({Bucket: 'myBucket', Key: candidate.resumeS3Key}).wait();
response.writeHead(200, {'Content-Type': data.ContentType});
response.end(data.Body);
}
});
});
这篇关于如何通过流星铁路由器从S3提供文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!