node.js 组件_使用Node.js和TransloadIt构建用户头像组件

node.js 组件

在本系列的第一部分中,我们介绍了TransloadIt —一种文件处理服务,专门处理图像,视频和音频。 如果您还没有阅读它,我建议您立即阅读,因为它涵盖了很多背景概念,您需要阅读这些概念才能继续阅读本部分。

但是,有了足够的推理,背景和理论,我们来看一个实际的示例,说明如何使用该服务处理您自己的应用程序中的某些图像。

出于本教程的目的,我们将为任意应用程序实现用户个人资料照片功能。 我们将使用TransloadIt执行以下操作:

  1. 拦截文件上传,而不是将其上传到您的应用程序,而是上传到其服务器。
  2. 执行服务器端文件检查,以确保它满足某些条件,例如它是否确实是映像。
  3. 创建上载图像的许多不同派生形式(例如大小),例如各种尺寸的缩略图以及用户个人资料页面的“中”和“大”版本。
  4. 将所得衍生产品转移到Amazon S3存储桶。
  5. 在我们的应用程序中显示新上传图像的缩略图。
  6. 使用从TransloadIt返回的信息,让我们的应用程序知道在哪里可以找到生成的图像,以便我们可以在用户记录中存储对它们的引用。

第一步是构建一些包含汇编指令的模板。

模板入门

模板包含JSON格式的汇编指令。 启动您喜欢的文本编辑器,开始一些JSON:

{

}

……让我们深入。

筛选档案

首先,我们将添加一个步骤,该步骤利用/ file / filter机器人检查上传的文件的MIME类型,以确保它是图像。 将以下内容添加到您的空JSON文档中:

"steps":
  "files": {
    "robot": "/file/filter",
    "accepts": [
      [
        "${file.mime}",
        "regex",
        "image"
      ]
    ],
    "error_on_decline": true
  },

让我们分解一下。

我们从密钥files确定的步骤开始。 您可以随心所欲地对其进行命名,但是在大多数情况下, files才有意义。

接下来,我们告诉TransloadIt使用/file/filter/机械手,该机械手用于对传入文件进行一些检查。 在这种情况下,我们告诉它要接受什么。 我们要求它提取文件的MIME类型并在其上运行一个正则表达式( image )。

在TransloadIt指令中,变量使用美元符号和大括号${} 。 指定正则表达式时,只需要指定它的主体即可。

如果我们设置的测试失败,则error_on_decline参数可确保引发错误,而不是继续进行下一步。

换句话说,我们告诉TransloadIt拒绝所有不是图像的文件。

添加调整大小步骤

现在,让我们再创建三个步骤,每个步骤都做同样的事情-创建传入图像的派生(即特定大小)。

我们可以随意调用这些步骤,因此我们将使用为派生类提供一些上下文的名称mediumlargethumbnail

让我们定义以下步骤的第一步:

"medium": {
  "use": ":original",
  "robot": "/image/resize",
  "width": 300,
  "height": 200,
  "resize_strategy": "fit"
},

在这里,我们定义了一个名为medium的步骤,该步骤利用了/image/resize机械手。 这需要许多参数,其中许多是可选的,这些参数在此处记录

use参数告诉它调整原始文件的大小。

在这种情况下,我们将提供所需的尺寸-300 x 200像素-并指定调整大小策略。 可用的调整大小策略记录在这里 ,但本质上fit确保了图像被调整大小以适应指定的尺寸,同时保持高宽比。

免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费

large步骤实际上是相同的:

"large": {
  "use": ":original",
  "robot": "/image/resize",
  "width": 480,
  "height": 320,
  "resize_strategy": "fit"
},

然后thumbnail步骤:

"thumbnail": {
  "use": ":original",
  "robot": "/image/resize",
  "width": 80,
  "height": 80,
  "resize_strategy": "crop"
},

这次我们使用crop策略来确保最终得到的图像是完美的正方形。

为了使过程更高效,没有理由不设置use参数来告诉TransloadIt将缩略图基于已处理的大中型版本。

在此阶段,我们确保正在处理图像,并且已将其大小调整了三倍,以创建三个单独的图像导数。 接下来,我们将告诉TransloadIt如何处理新创建的派生类。

出口

如前所述,Transloadit不会长时间存储我们的文件-托管不是服务的全部内容-因此我们需要将文件移到更永久的位置。

我们将使用/s3/store文件导出机器人将文件上传到Amazon S3存储桶。

这是配置该步骤的方法:

"export": {
  "use": [
    "medium",
    "large",
    "thumbnail"
  ],
  "robot": "/s3/store",
  "path": "users/profiles/${fields.username}_${previous_step.name}.${file.ext}",
  "key": "YOUR-S3-AUTH-KEY",
  "secret": "YOUR-S3-AUTH-SECRET",
  "bucket": "YOUR-BUCKET-NAME"
}

您需要用自己的S3凭据和存储桶名称替换。

这比我们之前的步骤稍微复杂一些,所以让我们分解一下。

use参数告诉机器人对每个调整大小后的图像执行此步骤,从而在S3上为每次上传生成三个文件。 如您所见, mediumlargethumbnail匹配我们前面三个步骤的标识符。

然后,我们指定密钥(S3的路径术语),用于使用path配置值存储生成的文件。 此名称与存储桶的完全限定域名结合在一起,随后成为生成的派生图像的URI。

在上面的示例中,我们使用以下模式:

users/profiles/${fields.username}_${previous_step.name}.${file.ext}

这种模式首先在路径前面加上users/profiles/ ,然后使用一个名为username的隐藏表单字段的值,我们将在稍后定义它。 然后将其与定义上一步的键(即我们的派生名称)连接起来。 最后,它添加了原始文件的扩展名,可以通过${file.ext}变量访问该扩展名。

那是一个很大的嘴,所以也许最好用一个例子来说明。 给定用户名bob ,此模式将产生以下三个路径:

users/profiles/bob_medium.jpg
users/profiles/bob_large.jpg
users/profiles/bob_thumbnail.jpg

通过砍切和更改可用的变量,您可以采用各种命名策略。 敌人的例子,请考虑以下模式:

users/profiles/${fields.username}${file.meta.width}x${file.meta.width}.${file.ext}

通过串联用户名,结果文件的宽度和高度以及最后文件的扩展名,可以动态构造文件名。 这将导致如下所示:

users/profiles/bob480x320.jpg

请注意,如果图像小于导数的目标尺寸,则这些值将反映最终图像,而不是配置的尺寸。

要简单地使用原始文件名:

${file.name}

为了确保唯一性,以下变量提供了唯一的32个字符的前缀:

${unique_prefix}

有关可用变量的完整列表,请参阅文档中有关汇编程序变量的部分

上载范本

将所有这些步骤放在一起,组成模板的组装说明如下所示:

{
  "steps": {
    "files": {
      "robot": "/file/filter",
      "accepts": [
        [
          "${file.mime}",
          "regex",
          "image"
        ]
      ],
      "error_on_decline": true
    },
    "medium": {
      "use": ":original",
      "robot": "/image/resize",
      "width": 300,
      "height": 200,
      "resize_strategy": "fit"
    },
    "large": {
      "use": ":original",
      "robot": "/image/resize",
      "width": 480,
      "height": 320,
      "resize_strategy": "fit"
    },
    "thumbnail": {
      "use": ":original",
      "robot": "/image/resize",
      "width": 80,
      "height": 80,
      "resize_strategy": "crop"
    },
    "export": {
      "use": [
        "medium",
        "large",
        "thumbnail"
      ],
      "robot": "/s3/store",
      "path": "users/profiles/${fields.username}_${previous_step.name}.${file.ext}",
      "key": "YOUR-S3-AUTH-KEY",
      "secret": "YOUR-S3-AUTH-SECRET",
      "bucket": "YOUR-BUCKET-NAME"
    }
  }
}

在适当的位置输入您自己的S3凭据,然后我们准备将模板上传到TransloadIt。

本教程随附的示例代码存储库中,您可以在名为template.json的文件中找到上述JSON。

如果您尚未使用TransloadIt创建帐户, 则现在要这样做

您需要登录; 然后转到您的信息中心(我的帐户)。 在左侧边栏中的集成下,选择模板 。 然后,单击右上角的“ 新建”按钮。

系统会要求您提供一个名称来标识您的模板-像user_avatars这样的东西就可以了。 然后,粘贴到上面的JSON(您还将在本文随附的存储库的根目录中找到该JSON)中-确保已用您自己的JSON替换了虚拟S3值,然后点击Save

如果您想使用其他存储机制,例如(S)FTP或Rackspace Cloud Files,则可以在此处找到相关文档-只需相应地修改最后一步即可。

您将被带回到主模板文件,并且您会注意到为新创建的模板分配了一个哈希作为唯一ID。 记下这一点,因为稍后将需要它。

完成之后,让我们看一下如何从应用程序中使用TransloadIt。

示例应用

您可以在Github上找到一个示例应用程序来伴随本教程。

为了运行它,您需要确保已安装以下先决条件:

  • Node.js
  • npm
  • MongoDB
  • 凉亭

Vagrant用户将在存储库中找到一个Vagrant Vagrantfile ,以创建包含所有列出的依赖项的VM。

本质上,它是一个简单的Express应用程序。 为简洁起见,我们在这里不涉及很多内容:

  • 它使用config模块将应用程序的配置保存在.yaml文件中。
  • 它使用Mongoose和MongoDB来定义用户模型。
  • 它使用PassportLocal策略来提供简单的身份验证机制。
  • 它提供了中间件来安全地对密码进行哈希处理。
  • 它包含一些简单的中间件,以将某些路由限制为仅通过身份验证的用户。
  • 它使用Handlebars,以及handlebars-layouts包来处理模板。

首先,克隆应用程序,然后安装依赖项:

npm install
bower install

该应用程序中有几个元素值得简要介绍。

这是User模型的架构定义:

var userSchema = mongoose.Schema({
  username : { type: String, required: true, unique: true },
  email    : { type: String, required: true, unique: true },
  password : { type: String, required: true },
  avatar   : { type: mongoose.Schema.Types.Mixed, required: false }
});

注意我们如何包含类型为Mixedavatar字段。 这将使我们能够将化身指定为哈希,例如:

user.avatar = {
  thumbnail : 'http://your.bucket.name.aws.amazon.com/user/profile/bob_thumbnail.jpg',
  medium    : 'http://your.bucket.name.aws.amazon.com/user/profile/bob_medium.jpg',
  large     : 'http://your.bucket.name.aws.amazon.com/user/profile/bob_large.jpg'
};

现在基本结构已经就绪,让我们看一下TransloadIt的jQuery插件。

jQuery插件

在客户端与TransloadIt集成的最简单方法是使用官方的jQuery插件 ,尽管还有其他替代方法,我们将在本文后面看到。

可通过以下URL获得该插件的最新版本:

https://assets.transloadit.com/js/jquery.transloadit2-latest.js

最小集成涉及以下步骤:

  • 您将插件绑定到表单
  • 插件“劫持”表单提交,直接将文件发送到Transloadit
  • 插件等待,直到文件已上传并处理
  • Transloadit返回带有结果的JSON对象,该对象还将包含新生成文件的URL
  • 它会创建一个隐藏的textarea元素,其中包含来自Transloadit的JSON
  • 表格已提交给您的申请

这是初始化插件,告诉它使用模板的非常简单的示例:

$(function() {
  $('#upload-form').transloadit({
    wait: true,
    params: {
      auth: {
        key: 'YOUR-AUTH-KEY'
      },
      template_id: 'YOUR-TEMPLATE-ID'
    }
  });
});

但是,正如我们在上一部分中指出的那样,在客户端代码中公开身份验证凭据不是一个好主意。 相反,我们将使用签名。

签名

签名是使用身份验证令牌的一种更安全的选择,尽管它们需要一些服务器端的工作。

本质上,使用签名要求您不要对客户端应用程序发送一堆指令到TransloadIt,而是对指令进行编码,并使用HMAC算法和专用认证密钥对它们进行加密。 结果生成了一个临时令牌(即签名),该令牌仅限于特定的指令组合。 因为它是临时的,所以如果该令牌被破坏,那么它将很快变得无用。

您不必担心自己生成签名的来龙去脉,因为我们可以使用第三方库来处理该过程。 如果您使用的是Node.js,则官方SDK将为您处理。

要安装库:

npm install transloadit --save

您需要身份验证密钥和身份验证密钥,可以从TransloadIt网站上的“ API凭据”部分获得。 将它们放在config\default.yaml的相关部分。

您需要通过将RENAME_THIS_TO_default.yaml重命名或复制到default.yaml来创建默认配置文件。

现在,创建TransloaditClient类的实例,并为其提供身份验证详细信息:

var TransloaditClient =   require('transloadit');
var transloadit       =   new TransloaditClient({
      authKey     : config.transloadit.auth_key,
      authSecret  : config.transloadit.auth_secret
    });

接下来,定义要执行的操作的参数。 可以采用一组汇编指令的形式:

var params = {
  steps: {
    // ...
  }
};

或者,就我们而言,我们只需提供模板的ID:

var params = {
  template_id: 'YOUR-TEMPLATE-ID'
};

要创建签名:

var sig = transloadit.calcSignature(params);

这将导致散列包含签名(各种访问令牌)以及调用服务所需的参数。 因此,我们的sig对象将如下所示:

{
  signature: "fec703ccbe36b942c90d17f64b71268ed4f5f512",
  params: {
    template_id: 'YOUR-TEMPLATE-ID',
    auth: {
    	key: 'idfj0gfd9igj9dfjgifd8gfdj9gfdgf',
    	expires: '2015-06-25T10:05:35.502Z'
    }
  }
}

为了将其传递给我们的Handlebars模板,以便我们JavaScript可以利用它,我们需要创建一个非常简单的助手:

app.engine('.hbs', exphbs(
  {
    extname: '.hbs',
    defaultLayout: 'default',
    helpers : {
      json : function(context) {
        return JSON.stringify(context);
      }
    }
  }
));

现在让我们一起来定义account路由,其中​​将包括我们的头像上传表格:

// The account page
app.get('/account', ensureAuthenticated, function(req, res){

  // Require the TransloadIt client
  var TransloaditClient = require('transloadit');
  
  // Create an instance of the client
  var transloadit       =   new TransloaditClient({
    authKey     : config.transloadit.auth_key,
    authSecret  : config.transloadit.auth_secret
  });

  // Build the Transloadit parameters...
  var params = {
    template_id 	: 	config.transloadit.template_id
  };

  // ...and generate the signature
  var sig = transloadit.calcSignature(params);  

  return res.render('account', {
    user: req.user,
    sig : sig
  });
});

然后,在相应的模板( views/account.hbs )中,让我们从一些非常简单HTML开始:

<h2>Hello, {{ user.username }}</h2>

{{# if user.avatar }}
<img src="{{ user.avatar.thumbnail }}" id="avatar">
{{else}}
<img src="/avatar.png" id="avatar">
{{/if}}

<form method="POST" action="/avatar" id="avatar-form">
  <input type="file" name="image" id="avatar-upload">
  <input type="hidden" name="username" value="{{user.username}}">
</form>

请注意,我们包括一个包含用户名的隐藏字段。 我们将根据请求将其发送到TransloadIt,以便可以在我们的模板中使用它。

现在添加JavaScript,首先使用我们的json Handlebars帮助器进行一些变量初始化:

var sig = {{{ json sig }}};

现在,我们将TransloadIt插件绑定到上传表单:

$(function() {
  $('#avatar-form').transloadit({
    wait: true,
    params: JSON.parse(sig.params),
    signature: sig.signature,
    fields: true,
    triggerUploadOnFileSelection: true,
    autoSubmit: false,
    onSuccess: function(assembly) {
      $('img#avatar').attr('src', assembly.results.thumbnail[0].url + '?' + (new Date()).getTime() );
      var derivatives = {
        thumbnail : assembly.results.thumbnail[0].url,
        medium : assembly.results.medium[0].url,
        large : assembly.results.large[0].url
      };
      $.ajax({
        type: 'post',
        url: '/avatar',
        data: derivatives,
        success: function(resp){
          console.log(resp);
        }
      })
    }
  });
});

这比我们之前介绍的最小集成初始化要复杂得多,因此让我们一次来进行一下了解。

我们从sig变量中获取参数和签名,该变量是在服务器上生成的,然后编码为JSON。 因为params部分是嵌套的,所以我们使用JSON.parse()将其转换回一个对象,然后TransloadIt将从中提取相关参数。

在插件初始化中, wait设置为true ,这意味着我们要等到两个文件都已上传并且已对其进行处理。

使用程序集通知 (您可以在稍后的“高级用法”部分中进行了解)意味着您不必等待文件被处理,在这种情况下,您可以将wait设置为false

fields设置为true可以告诉插件我们在发送文件进行处理时希望包括其他信息; 在我们的例子中,这是一个名为username的隐藏表单字段,我们使用经过身份验证的用户的username填充该字段。

一旦用户选择了文件,而不是提交表单时,使用triggerUploadOnFileSelection将文件发送到Transloadit。 一旦结果从Transloadit返回时, autoSubmit阻止它提交表单,因为我们将自己手动进行操作。

当数据从Transloadit返回时,将触发onSuccess回调,这为我们提供了assembly中数据的哈希值。

assembly对象包含一个results属性,该属性又包含我们每个“步骤”的属性。 这些包含文件对象数组。 由于我们仅上传一个文件,因此它们将是包含单个项目的数组。 每个文件对象都包含许多属性,包括原始文件名,元信息,Transloadit的唯一ID以及其他细节。 要查看全部信息,您可能希望将其注销到控制台中并进行查看。 但是,我们真正感兴趣的只是url属性,其中包含S3上生成的图像的URL。

或者,您可能希望使用ssl_url属性,该属性与url相同,但通过HTTPS。

我们只是通过对应的派生名称提取三个URL,然后创建这三个派生及其对应URL的哈希。

为了向用户提供视觉反馈,我们还获取了缩略图的URL并修改页面上的头像以显示新上传的图像。

最后,我们使用Ajax将数据以静默方式发布回我们的应用程序。

这是捕获该数据的avatar路线:

// Ajax callback for setting the avatar
app.post('/avatar', ensureAuthenticated, function(req, res){
  req.user.avatar = req.body
  req.user.save(function(err) {
    if(err) {
      return res.send('error');
    }
    return res.send('ok');
  });
});

在生产中,您可能需要对此进行清理和验证。

如您所见,我们获取派生图像及其URL的哈希,从req.user获取当前经过身份验证的用户,将avatar属性设置为提供的哈希,然后更新用户模型。

这只是一种可能的方法。 为了获得更快的反馈,您可能希望使用插件的onResult回调在缩略图生成后立即获取它,而不是等待所有三个派生类。 与其使用客户端代码中的Ajax调用来通知服务器,不如选择使用Assembly通知功能,该功能提供了在后台运行程序集的其他好处,而不是在客户端上阻止执行。 请查阅插件文档以获取所有选项。

到此结束我们的基本应用。 别忘了,所有源(包括身份验证机制)都在Github结束了

高级用法

在总结之前,让我们简单地看一下TransloadIt的两个更高级的方面。

其他客户端选项

您不必使用提供的jQuery插件。 在文档的“ 社区项目”部分中,您可以找到许多替代方法,包括Bootstrap插件, drag n'drop插件, Angular插件或对简单的旧XHR的支持。

您可能需要更详细地了解XHR。 这是一个简单的解决方案,提供了很大的灵活性,同时要求您提供自己的反馈(例如某种上传指示器)。 还值得注意的是,一旦上传了文件,它将尝试通过以1000ms的间隔轮询服务器来确定何时完成了程序集。

通知事项

当文件准备好时,您可以使用通知来ping您的应用程序,而不必让用户等待处理他们的上载。 使用这种方法,用户只需等到上传完成即可。

从消费者的角度来看,通知很容易实现; 只需在您的汇编指令中包含notify_url即可,例如:

{
  auth       : { ... },
  steps      : { ... },
  notify_url : "http://example.com/webhooks/incoming/transloadit"
}

当您的URL被Transloadit ping通时,提供的JSON将包含一个signature字段,您可以使用该字段来验证通知确实来自他们。 只需使用您的身份验证密钥对签名进行解码即可。

在开发过程中,您可能希望利用此代理软件包来测试程序集通知,或使用隧道服务(例如ngrok)

摘要

在这个由两部分组成的系列文章中,我们对文件处理服务TransloadIt进行了全面介绍。

在第一部分中,我们研究了一些优点和缺点,然后研究了关键概念。

这一部分,我们动手了,并使用jQuery,Node.js和Express构建了一个简单的用户头像组件。

您不仅限于jQuery,而且确实可以自由使用原始JavaScript解决方案或您喜欢的框架。 您甚至不需要在客户端应用程序中使用它,而在服务器端技术方面,您可以选择很多。 不过,希望您现在对如何将其用于图像处理有所了解。

您在项目中使用TransloadIt吗? 您知道更好的服务吗? 在评论中让我知道。

翻译自: https://www.sitepoint.com/user-avatar-component-node-js-transloadit/

node.js 组件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值