使用Meteor(CFS)下载远程图像

时间:2014-09-03 23:06:32

标签: node.js http encoding meteor

所以,我试图弄清楚如何下载远程图像,然后使用CollectionFS存储下载的图像。

我正在尝试在CFS中使用自动URL处理,但我正在下载图像的主机 - 禁用了HEAD请求,因此我无法使用它。

我要么使用Meteor.get,要么使用NPM的“请求”,但我真的不明白如何将两者合并以获得所需的结果。

任何想法都会受到高度赞赏。我所知道的只是在Meteor.get请求中使用URL,但在那之后,我真的迷路了。

这是我到目前为止所得到的,但我不知道如何处理请求的结果:

var result = HTTP.get(url);

我只假设我应该对result.body做一些事情(根据Meteor文档),但我不知道如何正确编码该对象,以便可以将其推送到本地的CFS集合中。

2 个答案:

答案 0 :(得分:6)

从我在CollectionFS API上看到的内容,服务器端插入可以将Node.js Buffer对象作为参数。

https://github.com/CollectionFS/Meteor-CollectionFS#getting-started

Buffer对象是您从npm request包中获得的,encoding设置为null,这是您希望插入的内容CollectionFS。

如果我们没有将encoding设置为null,则响应将通过字符串编码,这将破坏我们的图像数据,因为这是原始二进制文件。

不幸的是你不能使用Meteor HTTP包来执行此操作,因为它充当npm request的包装器,并且特别强制编码为utf-8,如第74行所示:

https://github.com/meteor/meteor/blob/devel/packages/http/httpcall_server.js#L74

您可能知道,npm软件包不能直接在Meteor中使用,因为服务器端环境依赖于Fiber

所以这是必要的包装请求,作为一个尚未发布的包:

/packages/request/package.js :

Package.describe({
  summary:"Simplified HTTP request client",
  version:"2.40.0"
});

Npm.depends({
  "fibers":"1.0.1",
  "request":"2.40.0"
});

Package.onUse(function(api){
  //
  api.versionsFrom("METEOR@0.9.0.1");
  //
  api.use("underscore","server");
  //
  api.addFiles("server/lib/request.js","server");
  //
  api.export("request","server");
});

/packages/request/server/lib/request.js

var Future=Npm.require("fibers/future");
request=Npm.require("request");

var requestSync=function(uri,options){
  var future=new Future();
  request(uri,options,function(error,response,body){
    if(error){
      console.log(error);
      throw error;
    }
    future.return({
      response:response,
      body:body
    });
  });
  return future.wait();
};

_.extend(request,{
  putSync:function(uri,options){
    options.method="PUT";
    return requestSync(uri,options);
  },
  patchSync:function(uri,options){
    options.method="PATCH";
    return requestSync(uri,options);
  },
  postSync:function(uri,options){
    options.method="POST";
    return requestSync(uri,options);
  },
  headSync:function(uri,options){
    options.method="HEAD";
    return requestSync(uri,options);
  },
  delSync:function(uri,options){
    options.method="DELETE";
    return requestSync(uri,options);
  },
  getSync:requestSync
});

然后你可以使用这样的请求:

var result=request.getSync(url,{
  encoding:null
});
var buffer=result.body;

buffer变量将保存您需要传递给CollectionFS插入的未更改图像数据。

答案 1 :(得分:1)

在某些时候,Meteor添加npmRequestOptions作为覆盖这种情况的合理默认值的方法。

您现在可以简单地执行

HTTP.get(url, {npmRequestOptions: {encoding: 'binary'}})

获取正确的图像数据