我的目标:
显示一个对话框,提示用户保存从aws下载的文件。
我的问题:
我目前正在使用awssum-amazon-s3创建下载流。但是我只是设法将文件保存到我的服务器或将其流式传输到命令行......正如您从我的代码中看到的,我最后的尝试是尝试手动设置失败的内容处置标头。我不能使用res.download(),因为标题已经设置好了吗?
我如何实现目标?
我的节点代码:
app.post('/dls/:dlKey', function(req, res, next){
// download the file via aws s3 here
var dlKey = req.param('dlKey');
Dl.findOne({key:dlKey}, function(err, dl){
if (err) return next(err);
var files = dl.dlFile;
var options = {
BucketName : 'xxxx',
ObjectName : files,
};
s3.GetObject(options, { stream : true }, function(err, data) {
// stream this file to stdout
fmt.sep();
data.Headers['Content-Disposition'] = 'attachment';
console.log(data.Headers);
data.Stream.pipe(fs.createWriteStream('test.pdf'));
data.Stream.on('end', function() {
console.log('File Downloaded!');
});
});
});
res.end('Successful Download Post!');
});
我的角度代码:
$scope.dlComplete = function (dl) {
$scope.procDownload = true;
$http({
method: 'POST',
url: '/dls/' + dl.dlKey
}).success(function(data/*, status, headers, config*/) {
console.log(data);
$location.path('/#!/success');
}).error(function(/*data, status, headers, config*/) {
console.log('File download failed!');
});
};
此代码的目的是让用户使用生成的密钥下载文件一次。
答案 0 :(得分:33)
这是在最新版本的aws-sdk
上使用流媒体的整个代码var express = require('express');
var app = express();
var fs = require('fs');
app.get('/', function(req, res, next){
res.send('You did not say the magic word');
});
app.get('/s3Proxy', function(req, res, next){
// download the file via aws s3 here
var fileKey = req.query['fileKey'];
console.log('Trying to download file', fileKey);
var AWS = require('aws-sdk');
AWS.config.update(
{
accessKeyId: "....",
secretAccessKey: "...",
region: 'ap-southeast-1'
}
);
var s3 = new AWS.S3();
var options = {
Bucket : '/bucket-url',
Key : fileKey,
};
res.attachment(fileKey);
var fileStream = s3.getObject(options).createReadStream();
fileStream.pipe(res);
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('S3 Proxy app listening at http://%s:%s', host, port);
});
答案 1 :(得分:12)
此代码适用于最新的库:
package org.sampletest;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.ui.IWorkbench;
import org.junit.Test;
import com.example.myplugin.MyPlugin
public class MyPluginTest{
@Test
public void testMyPlugin() throws Exception{
// assume an empty workspace - "Run as JUnit Plugin Test can be configured to clear the workspace before each run.
String name = "myPluginTestProject";
IProjectDescription = ResourcesPlugin.getWorkspace().newProjectDescription(name);
IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(name);
project.create(desc, new NullProgressMonitor());
project.open(new NullProgressMonitor());
IFile file = project.getFile("myPluginTestFile");
InputStream source = getClass().getClassLoader().getResourceAsStream("sampleFile");
file.create(source, IFile.FORCE, null);
// Assuming MyPlugin has some operation on an IStructuredSelection
MyPlugin plugin = new MyPlugin();
IStructuredSelection selection = new StructuredSelection(file);
plugin.invoke(selection);
// Make some assertions...
}
}
答案 2 :(得分:8)
只需从S3和WriteStream创建一个ReadStream到您要下载的位置。查找下面的代码。对我来说很完美:
var AWS = require('aws-sdk');
var path = require('path');
var fs = require('fs');
AWS.config.loadFromPath(path.resolve(__dirname, 'config.json'));
AWS.config.update({
accessKeyId: AWS.config.credentials.accessKeyId,
secretAccessKey: AWS.config.credentials.secretAccessKey,
region: AWS.config.region
});
var s3 = new AWS.S3();
var params = {
Bucket: '<your-bucket>',
Key: '<path-to-your-file>'
};
let readStream = s3.getObject(params).createReadStream();
let writeStream = fs.createWriteStream(path.join(__dirname, 's3data.txt'));
readStream.pipe(writeStream);
答案 3 :(得分:6)
您已经确定了解决问题的最重要因素:您可以将来自S3的文件流传输到任何可写流,无论是文件流......还是将发送到客户端的响应流!
s3.GetObject(options, { stream : true }, function(err, data) {
res.attachment('test.pdf');
data.Stream.pipe(res);
});
请注意使用res.attachment
来设置正确的标头。您还可以查看有关流和S3的this answer。