使用Sendgrid / Nodemailer将Angular表单数据发布到Node.js [英] Post Angular form data to Node.js with Sendgrid/Nodemailer

查看:97
本文介绍了使用Sendgrid / Nodemailer将Angular表单数据发布到Node.js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已关注这个例子将我的Angular应用程序中的数据发布到Node.js以将webform发布到Sendgrid。这在一些变化后工作正常,并且非常感谢快速入门。将表单数据发布到Sendgrid现在正在运行!

I have followed this example to post data from my Angular app to Node.js to post a webform to Sendgrid. This works fine after some changes and thanks a lot for the quickstart. Posting my form data to Sendgrid is working now!

对于这个项目,我正在使用 Angular Fullstack 能够在我的Angular应用程序中使用Node功能。

For this project i'm using Angular Fullstack to be able to use Node functionalities within my Angular app.

但是,这个例子只是输入田野和文本区域。我希望能够添加文件(PDF,Docx,例如),以便人们可以通过Sendgrid向收件人发送附件。我搜索了一个解决方案,但找不到一个有效的例子。也许是因为我想要实现的目标是不可能的。

However, this example has just input fields and a textarea. I want to be able to add a file (PDF, Docx, e.g) so that people can send an attachment to the recipient via Sendgrid. I have searched for a solution but couldn't find a working example. Maybe because it is not possible what i want to achieve.

我的观点(客户):

<div ng-controller="ContactFormCtrl" id="contactformbox" style="margin-top:50px;" class="mainbox" >                    
  <div class="panel panel-info" >

          <div class="panel-heading">
              <div class="panel-title">Solliciteer direct</div>
          </div>     

          <div style="padding-top:30px" class="panel-body" >
              <form id="loginform" class="form-horizontal" role="form" name="contactform">

                  <div style="margin-bottom: 25px" class="input-group">
                    <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                    <input type="email" name="to" ng-model="email.to" ng-required="true" id="email-to" class="form-control" name="username" value="" placeholder="The emailadres from the employer">       
                  </div>

                  <div style="margin-bottom: 25px" class="input-group">
                      <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                      <input type="email" name="from" ng-model="email.from" ng-required="true" id="email-from" class="form-control" name="email-from" placeholder="Your e-mail address">
                  </div>

                  <div style="margin-bottom: 25px" class="input-group">
                      <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                      <input type="text" name="subject" ng-model="email.subject" ng-required="true" id="email-subject" class="form-control" name="subject" placeholder="Your subject please">
                  </div>

                  <div style="margin-bottom: 25px" class="input-group">
                      <input type="file" name="file" ng-model="email.file" ng-required="true" id="email-file" class="form-control" name="file">
                  </div>

                  <div style="margin-bottom: 25px" class="input-group">
                    <textarea ng-model="email.text" name="text" placeholder="Enter Text Here.." class="form-control" rows="5" id="comment"></textarea>
                  </div>    

                  <div style="margin-top:10px" class="form-group">
                      <!-- Button -->
                      <div class="col-sm-12 controls">
                            <button id="emailSubmitBn" class="btn btn-success" type="submit" ng-click="submitEmail()">Submit</button>
                      </div>
                  </div>
              </form>     
        </div>                     
  </div>  

MY CONTROLLER(客户端):

angular.module('angularMyApp')
.controller('ContactFormCtrl', function ($scope, $http) {
  $scope.submitEmail = function() {

    console.log("TEST");
    //Request
    $http.post('/api/email', $scope.email) 
    .success(function(data, status) {
        console.log("Sent ok");
    })
    .error(function(data, status) {
        console.log("Error");
    })
  };
});

我的APP.JS(服务器):

'use strict';

// Set default node environment to development
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

var express = require('express');
var config = require('./config/environment');
var http = require('http');
var bodyParser = require('body-parser');

var options = {
    auth: {
        api_key: process.env.SENDGRID_APIKEY; 
    }
}

var nodemailer = require('nodemailer');
var sgTransport = require('nodemailer-sendgrid-transport');

// Setup server
var app = express();
var server = require('http').createServer(app);
require('./config/express')(app);
require('./routes')(app);

var mailer = nodemailer.createTransport(sgTransport(options));

app.post('/api/email', function(req, res) {
var mailOptions = {
    to: ['test@test.nl', req.body.to],
    from: req.body.from,
    subject: req.body.subject,
    text: req.body.text
};

mailer.sendMail(mailOptions, function(err, res) {
    if (err) { 
        console.log(err) 
    }
    console.log(res);
  });
});

// Start server
server.listen(config.port, config.ip, function () {
console.log('Express server listening on %d, in %s mode', config.port, app.get('env'));
});

// Expose app
exports = module.exports = app;

有两个主要问题:


  1. Clientside:如何在此表单中将附件从Angular发布到Node?我是否必须先上传文件,还是可以使用$ http.post将其发送到Node?或者我必须使用ng-file-upload?

  2. Serverside:如何向Sendgrid / Nodemailer发送附件。从服务器上的app.js向Sendgrid发送硬编码文件不起作用。邮件成功发送到Sendgrid,但它不包含附件。

非常感谢提前!

推荐答案

1。上传带有格式的文件



您遇到的第一个问题是 ng-model 不起作用使用< input type =file/> 。因此,您需要创建一个自定义指令来使用该文件填充模型。

1. Uploading a file with a form in angular

The first trouble you have is that ng-model doesn't work with <input type="file" />. So, you will need to create a custom directive to populate the model with the file.

.directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            var model = $parse(attrs.fileModel);
            var modelSetter = model.assign;

            element.bind('change', function(){
                scope.$apply(function(){
                    modelSetter(scope, element[0].files[0]);
                });
            });
        }
    };
}]);

然后在你的文件输入元素上使用这个指令:

Then use the directive on your file input element like this:

<input type="file" file-model="email.attachment" ng-required="true" id="email-attachment" name="attachment" class="form-control" />

请注意,我将 email.file 更改为 email.attachment 以避免混淆其余代码。

Note that I changed email.file to email.attachment to avoid confusion in the rest of the code.

接下来,您需要包含该文件你的AJAX请求。您需要使用 FormData 。使用 FormData.append从范围填充它()

Next, you need to include the file in your AJAX request. You will need to use FormData for that. Populate it from the scope using FormData.append():

$scope.submitEmail = function() {
    var formData = new FormData();
    Object.keys($scope.email).forEach(function(key) {
        formData.append(key, $scope.email[key]);
    });
    $http.post('/api/email', formData, {
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
    }).then(function(data, status) {
        console.log("Sent ok");
    }, function(data, status) {
        console.log("Error");
    });
};

注意我还将配置对象传递给 $ http.post()。这是为了防止角度解析 FormData 对象并设置内容类型。

Notice I also passed a config object to $http.post(). This is to prevent angular from parsing the FormData object and setting the content type.

我非常依赖此博客文章。

要访问Express中的文件,请使用 multer

To access the file in express, use multer.

安装:

$ npm install --save multer

用法:

var multer = require('multer');
var upload = multer();

app.post('/api/email', upload.single('attachment'), function(req, res) {
    // req.file contains the 'attachment' file
    ...
});

来自 Nodemailer的电子邮件字段自述文件,它说要使用附件属性,该数组是 附件对象

From Nodemailer's Readme section on email fields it says to use an attachments property that is an array of attachment objects.

app.post('/api/email', upload.single('attachment'), function(req, res) {
    var mailOptions = {
        to: ['test@test.nl', req.body.to],
        from: req.body.from,
        subject: req.body.subject,
        text: req.body.text,
        attachments: [
            {
                filename: req.file.originalname,
                content: req.file.buffer
            }
        ]
    };

    mailer.sendMail(mailOptions, function(err, res) {
        if (err) { 
            console.log(err) 
        }
        console.log(res);
    });
});

上面的示例将附件保留在内存中,如果频繁上传大文件,这可能会很糟糕。您可以将文件写入磁盘:

The above example keeps the attachment in memory, which could be bad if large files are uploaded frequently. You can write files to disk instead:

var upload = multer({ dest: '/uploads' });

然后,而不是设置文件的缓冲区作为附件的内容,您可以将附件的路径设置为文件的路径

Then, instead of setting the file's buffer as the attachment's content, you would set the attachment's path to the file's path:

attachments: [
    {
        filename: req.file.originalname,
        path: req.file.path
    }
]

这篇关于使用Sendgrid / Nodemailer将Angular表单数据发布到Node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆