admin管理员组文章数量:1334949
I upload images to server with gridfs in my sails.js Application. My uploading codes are as follows
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()
});
});
}
I get the following response from this...
{
"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": {}
}
My question is , if I need to download the uploaded file above , what shall I do ? I got the following code in the internet for downloading task but this does not make much sense to me. Basically I want the download url of the uploaded image that I can use that url in Mobile App to show image.
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/dbname.images'
});
blobAdapter.read(filename, callback);
Can anybody help me on this ? Thanks in advance.
I upload images to server with gridfs in my sails.js Application. My uploading codes are as follows
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()
});
});
}
I get the following response from this...
{
"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": {}
}
My question is , if I need to download the uploaded file above , what shall I do ? I got the following code in the internet for downloading task but this does not make much sense to me. Basically I want the download url of the uploaded image that I can use that url in Mobile App to show image.
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/dbname.images'
});
blobAdapter.read(filename, callback);
Can anybody help me on this ? Thanks in advance.
Share Improve this question asked Jan 8, 2015 at 20:26 ayonayon 2,1802 gold badges19 silver badges32 bronze badges2 Answers
Reset to default 9After some research, I finally managed to solve the problem. I get the field fd
in the response after file upload and save that to use afterwards. I went to the skipper-gridfs
codes and found a 'read'
method that accept that value and returns the required file. So, I just pulled that file from mongo by that method and send as a response. It's working file.
download: function (req, res) {
var blobAdapter = require('skipper-gridfs')({
uri: 'mongodb://localhost:27017/mydbname.images'
});
var fd = req.param('fd'); // value of fd es 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));
}
});
}
I hope it will help somebody like me in the future :)
To add to Ayon's excellent answer above, here's a version of the same code that demonstrates streams, persisted file metadata, a dynamic content type, and a couple of other related ments:
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);
});
}
Why the stream?
This streaming approach saves us from loading the entire file into memory on our server (which would other bee a problem when dealing with large files, or with many concurrent downloads)
The error handler
Since we're dealing with a raw Node stream/emitter in userland code here, we must be sure to bind an 'error' event handler before doing anything-- just in case. (This prevents any unexpected stream errors from crashing the process.)
"open" vs. "save file as"
You could use a request parameter as a flag to determine how to set the content-disposition header -- and thus whether the user's browser/device/native app should "open" vs. "save as" the file.
Custom config
This example demonstrates setting up some custom config. e.g. in config/custom.js, you might put: module.exports.custom = { fileUploads: { adapter: require('skipper-fs'), uri: 'mongodb://localhost:27017/mydbname.images' }, };
What about actions2?
If you're using actions2 (available in Sails v1.x and up), you can acplish the same thing as res.pipe()
~~and the related error handling~~ by simply passing through the stream directly to exits.success()
. (EDIT: Actually, I was wrong about the 2nd part of that-- just verified that still have to handle .on('error',...)
yourself.) Also, you'll still have to set the content type response header; i.e. env.res.contentType(fileRecord.contentType)
.
本文标签: javascriptDownload image from skippergridfs in SailsjsStack Overflow
版权声明:本文标题:javascript - Download image from skipper-gridfs in Sails.js - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742308287a2450356.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论