【问题标题】:How to generate images server-side in Meteor and serve them via Iron Router?如何在 Meteor 中生成图像服务器端并通过 Iron Router 提供它们?
【发布时间】:2017-05-31 21:24:29
【问题描述】:

正如标题所说,我只想在服务器上生成一个图像,然后通过 Iron Router 在浏览器中提供它。

这是我目前所拥有的:

服务器/methods.js

Meteor.methods({
  getImage(cardId, styleId) {
    var canvas = new Canvas(500, 200);
    var ctx = canvas.getContext('2d');

    ctx.font = '26px "Comic Sans"';
    ctx.fillText('Hello World', 50, 80);

    var buffer = canvas.toBuffer();
    buffer = canvas.toDataURL();

    return buffer;
  }
});

routes/routes.js

Router.route('/i/:cardid/:styleid.png', function() {
  var imgContent = Meteor.call('getImage', this.params.cardid, this.params.styleid);
  //imgContent = `<html><body><img src="${imgContent}"></body></html>`;

  this.response.writeHeader('200', {
    'Content-Type': 'image/png',
    'Content-Length': imgContent.length
  });

  this.response.write(imgContent);

  this.response.end();
}, {where: 'server'});

如果我取消注释 routes.js 中的行并注释掉 image/png 标头,我可以让图像显示在 HTML 图像标记内,但这不是我想要的,因为我只想提供服务实际图像,没有 HTML。

任何帮助将不胜感激。谢谢!

编辑 我也试过返回这个:

var buffer = canvas.toBuffer();
//buffer = canvas.toDataURL();

buffer = new Buffer(buffer, 'binary').toString('base64');

没有成功。

编辑 2 基本上我正在尝试这样做:NodeJS: serve png generated by node-canvas 但只有 Meteor、Canvas 和 Iron Router。

【问题讨论】:

  • 我不相信这在路由器中是可能的。路由器想要渲染一个 html 模板。 Meteor 将自动在模板周围添加&lt;html&gt;&lt;head&gt;...&lt;/head&gt;&lt;body&gt; &lt;/body&gt;&lt;/html&gt;

标签: javascript node.js meteor canvas iron-router


【解决方案1】:

我能够通过执行以下操作使其正常工作:

服务器/methods.js

Meteor.methods({
  getImage(cardId, styleId) {
    var canvas = new Canvas(500, 200);
    var ctx = canvas.getContext('2d');

    ctx.font = '26px "Comic Sans"';
    ctx.fillText('Hello World', 50, 80);

    return canvas.toBuffer();
  }
});

routes/routes.js

Router.route('/i/:cardid/:styleid.png', function() {
  var imgContent = Meteor.call('getImage', this.params.cardid, this.params.styleid);
  imgContent = new Buffer(imgContent, 'binary');

  this.response.writeHeader('200', {
    'Content-Type': 'image/png',
    'Content-Length': imgContent.length
  });

  this.response.write(imgContent);

  this.response.end();
}, {where: 'server'});

基本上只需要输出正确类型的数据!

【讨论】:

    【解决方案2】:

    我想了更多。您可以在onAfterAction() 中简单地执行以下操作

    document.type="img";
    document.location=url;
    

    但是这样做之后你会丢失路由器。

    您仍然会在结果页面中看到 html,因为如果您在浏览器中打开图像的 url,它会自动在其周围添加自己的 html 标记。为了证明这一点,只需右键单击此处的图像并选择“在新选项卡中打开图像”

    【讨论】:

    • 我不认为你的答案会做我想让它做的事情,因为我必须提供一个文件的 URL,但是没有一个,因为文件是生成的,我想要在浏览器中提供图像缓冲区。我很确定这是可能的,因为人们已经做了同样的事情来提供这样的文件内容:stackoverflow.com/questions/21565991/…
    【解决方案3】:

    您可以将 Picker 用于服务器端路由,因为它实现了 Node 的 ServerResponse 模块 [https://nodejs.org/api/http.html#http_class_http_serverresponse][1] [https://github.com/meteorhacks/picker/][1]

        Picker.route('/i/:cardid/:styleid.png', function(params, req, res, next) {
           var imgContent = Meteor.call('getImage', params.cardid, params.styleid);
    
      res.writeHead('200', {
        'Content-Type': 'image/png',
        'Content-Length': imgContent.length
      });
    
     res.end(imgContent);
        });
    

    【讨论】:

    • 我觉得这在 Iron Router 中是可能的
    • 那么您想公开data: 链接吗?这是可行的。
    • 我不完全确定,但听起来不错。我基本上想在用户访问 URL 时生成并提供图像。因此,如果我要做[img src="http://mywebsite.com/i/323/1.png"] 之类的事情。图片将根据路径生成。
    • 米歇尔弗洛伊德,你能给我更多关于公开data:链接的信息吗?我已经更新了我的原始帖子。
    猜你喜欢
    • 2014-03-27
    • 2016-08-26
    • 2015-02-27
    • 2013-09-03
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多