【发布时间】:2014-12-11 23:34:53
【问题描述】:
我在这里发布这个问题,我已经阅读了许多相关的帖子,但其中任何一个都帮助我使它工作。
这个想法很简单:我有一个基于 MEAN 的应用程序,可以在其中将图像上传到 GridFS - 无需将其本地存储到服务器 - 稍后在浏览器中将其可视化。
那么让我们开始吧。我正在使用 angular-file-upload 模块从 AngularJS 上传图像。因此,在我的一个 AngularJS 控制器中,我有:
$scope.onFileSelect = function(file) {
var fileName = file.name;
$scope.upload = $upload.upload({
url: '/file/uploadFile', //this is the node route for uploading the file
headers: {
'fileName':fileName
},
file: file
}).
success(function(data, status, headers, config) {
//DOING STUFF
}.
error(function(data, status, headers, config) {
//DOING OTHER STUFF
});
}
在我的 Node + Express 服务器中,我正在通过 grids-stream 模块处理上传请求和下载图像的请求。这使我可以直接在 GridFS 中/从 GridFS 中流式传输和保存图像,而无需暂时将其保存在服务器中。
var mongoose = require('mongoose'),Grid = require('gridfs-stream'),gfs;
mongoose.connection.once('open',function() {
gfs = Grid(mongoose.connection.db, mongoose.mongo);
});
exports.uploadFile = function(req, res) {
var fileNameHeader = req.headers['filename'];
//creating a unique filename
var name = uuid.v1();
var extIndex = fileNameHeader.lastIndexOf('.');
var extension = fileNameHeader.substr(extIndex);
var fileName = name+extension;
var writeStream = gfs.createWriteStream({
filename: fileName,
root: 'imagesGrid'
});
req.pipe(writeStream);
writeStream.on('close',function() {
//DOING STUFF
});
}
exports.downloadFile = function(req,res) {
var name = req.params.name;
var readStream = gfs.createReadStream({
filename: name,
root: 'imagesGrid'
});
res.header({'Content-type': mime.lookup(name)});
readStream.pipe(res);
};
在客户端,我有这个生成所有 HTML 图像元素的 HTML 指令:
<my-image-draggable ng-repeat="image in userImages">
</my-image-draggable>
其中 my-image-draggable 具有,作为其元素之一:
<img ng-src='{{image.imageId.location}}'>
在运行时,{{image.imageId.location}} 被翻译为(例如):'/file/getFile/2350bcf0-53b4-11e4-9f6b-9fc9a66908c4.jpg',因此,原则上
<img ng-src='/file/getFile/2350bcf0-53b4-11e4-9f6b-9fc9a66908c4.jpg'>
应该在服务器中向downloadFile 发起一个HTTP GET 请求,图像应该从GridFS 流式传输,最后显示在浏览器中。问题是图片没有显示出来。
我还尝试在 Angular 控制器中预处理服务器发送的图像数据,以便将其编码为 base64,并在运行时让 ng-src 类似于:
'data:image/jpeg;base64,'+Base64.encode(data);
但它也不起作用。
我也尝试手动调用downloadFile 路由,但没有结果。我无法弄清楚为什么这不起作用。我想知道图像是否正确保存到 GridFS。
有什么建议吗? 其他人遇到过同样的问题吗?
非常感谢!
【问题讨论】:
-
图片上传问题。如果我从位于服务器中的文件流式传输图像,则一切正常。我会尝试另一种方式进行上传。
-
我使用
socket.io-stream切换到通过Websocket 流式传输图像(因为我的应用程序已经有一个),它现在可以工作了。使用 angular-file-upload 上传文件的问题在于它是以多部分的形式发送的。在服务器端,当文件被接收并流式传输到数据库时,它的内容包含一些额外的信息,这些信息妨碍了它的正确可读性(当流回客户端时)。
标签: node.js angularjs gridfs angular-file-upload gridfs-stream