我在sails.js应用程序中使用gridfs将图像上传到服务器。我的上传代码如下
upload: function (req, res) {
req.file('avatar')
.upload({
adapter: require('skipper-gridfs'),
uri: 'mongodb://localhost:27017/dbname.images'
}, function whenDone(err, uploadedFiles) {
if (err) return res.negotiate(err);
else return res.ok({
files: uploadedFiles,
textParams: req.params.all()
});
});
}
我从这里得到以下回应......
{
"files": [
{
"fd": "2d8910a0-8ca2-4df1-9930-6ddd721a0416.jpg",
"size": 172883,
"type": "image/jpeg",
"filename": "Photo on 12-20-14 at 9.53 PM.jpg",
"status": "bufferingOrWriting",
"field": "avatar",
"extra": {
"fileId": "54aee6ced4a0e88f0dc9025f",
"fd": "2d8910a0-8ca2-4df1-9930-6ddd721a0416.jpg",
"dirname": "."
}
}
],
"textParams": {}
}
我的问题是,如果我需要下载上面上传的文件,我该怎么办?我在互联网上获得了以下代码来下载任务,但这对我来说没有多大意义。基本上我想要上传图片的下载网址,我可以使用移动应用程序中的网址来显示图片。
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/dbname.images'
});
blobAdapter.read(filename, callback);
有人可以帮我这个吗?提前谢谢。
答案 0 :(得分:9)
经过一番研究,我终于设法解决了这个问题。我在文件上传后的响应中得到字段fd
并保存以供后续使用。我转到skipper-gridfs
代码,找到了一个'read'
方法,接受该值并返回所需的文件。所以,我只是通过该方法从mongo中提取该文件并作为响应发送。这是工作文件。
download: function (req, res) {
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/mydbname.images'
});
var fd = req.param('fd'); // value of fd comes here from get request
blobAdapter.read(fd, function(error , file) {
if(error) {
res.json(error);
} else {
res.contentType('image/png');
res.send(new Buffer(file));
}
});
}
我希望它能在未来帮助像我这样的人:)
答案 1 :(得分:1)
为了添加Ayon上面的优秀答案,这里有一个相同代码的版本,用于演示流,持久文件元数据,动态内容类型以及其他一些相关注释:
download: function (req, res) {
if (!_.isString(req.param('fileId') && !_.isNumber(req.param('fileId')){
return res.badRequest('`fileId` should be provided as a string/number (depending on whether this is Mongo or MySQL, if you\'ve customized the primary key, etc.).');
}
// Look up file metadata
UploadedFile.findOne({ id: req.param('fileId') })
.exec(function (err, fileRecord) {
if (err) { return res.serverError(err); }
if (!fileRecord) { return res.notFound(); }
// Get configured blob adapter instance.
var blobAdapterOpts = _.omit(sails.config.fileUploads, 'adapter');
var configuredBlobAdapter = sails.config.fileUploads.adapter(blobAdapterOpts);
// Now locate the actual raw contents of the file using the
// `fd` that we saved elsewhere (i.e. when uploading), and then
// use the blob adapter to open up a stream of bytes (the file's
// contents) and pipe that down as the HTTP response body.
// (like skipping a rock across the surface of a pond)
var fileStream = configuredBlobAdapter.read(fileRecord.fd);
fileStream.on('error', function (err){
return res.serverError(err);
});
// Along the way, set the content-type for the response based on
// whatever we saved when this file was originally uploaded.
//
// (You could do the same thing for the filename, assuming this
// file download is the "save as" kind, as determined by the
// content-disposition header.)
res.contentType(fileRecord.contentType);
// Pipe the stream of file data through as our HTTP response body.
// (like skipping a rock on the surface of a pond)
return fileStream.pipe(res);
});
}
这种流媒体方法使我们无法将整个文件加载到 我们服务器上的内存(当其他时候会出现问题) 处理大文件,或许多并发下载)
因为我们正在处理userland中的原始节点流/发射器 代码在这里,我们必须确保绑定一个错误'事件处理程序 在做任何事之前 - 以防万一。 (这可以防止任何 崩溃过程中出现意外的流错误。)
您可以使用请求参数作为标志来确定方式 设置内容处置标题 - 从而是否 用户的浏览器/设备/本机应用应该"打开" vs."另存为" 文件。
此示例演示如何设置一些自定义配置。 例如在config / custom.js中,您可以放置: module.exports.custom = { fileUploads:{ 适配器:require(' skipper-fs'), uri:' mongodb:// localhost:27017 / mydbname.images' }, };
如果您正在使用actions2(在Sails v1.x及更高版本中可用),您可以完成与res.pipe()
〜〜相同的事情以及相关的错误处理~~只需通过流直接到exits.success()
。 (编辑:实际上,我错了第2部分 - 只有verified仍然需要自己处理.on('error',...)
。) ,您仍然需要设置内容类型响应标头;即env.res.contentType(fileRecord.contentType)
。