首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Sails.js中从skipper-gridfs下载图片

在Sails.js中从skipper-gridfs下载图片
EN

Stack Overflow用户
提问于 2015-01-09 04:26:57
回答 2查看 2.1K关注 0票数 4

我在我的sails.js应用程序中使用gridfs将图像上传到服务器。我的上传代码如下

代码语言:javascript
复制
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()
                });
            });
    }

我从这里得到了下面的响应...

代码语言:javascript
复制
{
    "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": {}
}

我的问题是,如果我需要下载上面上传的文件,我应该怎么做?我在互联网上得到了以下下载任务的代码,但这对我来说没有太大意义。基本上,我想要的下载网址的上传图像,我可以使用该网址在移动应用程序来显示图像。

代码语言:javascript
复制
var blobAdapter = require('skipper-gridfs')({
            uri: 'mongodb://localhost:27017/dbname.images'
        });
        blobAdapter.read(filename, callback);

有人能帮我解决这个问题吗?提前谢谢。

EN

回答 2

Stack Overflow用户

发布于 2015-01-10 03:54:02

经过一番研究,我终于设法解决了这个问题。我在文件上传后的响应中获得了字段fd,并将其保存以供以后使用。我找到了skipper-gridfs代码,找到了一个接受该值并返回所需文件的'read'方法。因此,我只是通过该方法从mongo中提取了该文件,并作为响应发送。这是工作文件。

代码语言:javascript
复制
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));
            }
        });
    }

我希望它能在未来帮助像我这样的人:)

票数 9
EN

Stack Overflow用户

发布于 2017-04-08 21:35:21

为了补充Ayon上面的精彩答案,这里是同一代码的一个版本,它演示了流、持久化文件元数据、动态内容类型和其他一些相关注释:

代码语言:javascript
复制
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代码中的原始Node流/发射器,所以我们必须确保在执行任何操作之前绑定一个“error”事件处理程序--以防万一。(这可以防止任何意外的流错误导致进程崩溃。)

打开“vs.”将文件另存为

您可以使用请求参数作为标志来确定如何设置content-disposition头--从而确定用户的浏览器/设备/本机应用程序是否应该“打开”或“另存为”文件。

自定义配置

这个例子演示了如何设置一些自定义配置。例如,在配置/定制.js中,你可以写: module.exports.custom ={ fileUploads:{适配器:需要(‘skipper-fs’),uri:'mongodb://localhost:27017/mydbname.images‘},};

那actions2呢?

如果您使用的是actions2 (在Sails v1.x和更高版本中可用),则可以通过直接将流传递到exits.success()来完成与res.pipe()相同的事情以及相关的错误处理。(__编辑:实际上,我对第二部分的看法是错误的--只是还需要自己处理.on('error',...)。)此外,您仍然需要设置内容类型响应头;即env.res.contentType(fileRecord.contentType)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27848934

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档