使用Sendgrid / Nodemailer将Angular表单数据发布到Node.js [英] Post Angular form data to Node.js with Sendgrid/Nodemailer
问题描述
我已关注这个例子将我的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;
有两个主要问题:
- Clientside:如何在此表单中将附件从Angular发布到Node?我是否必须先上传文件,还是可以使用$ http.post将其发送到Node?或者我必须使用ng-file-upload?
- 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屋!