使用Sendgrid/Nodemailer将Angular表单数据发送到Node.js
Post Angular form data to Node.js with Sendgrid/Nodemailer
我已经按照这个例子将数据从我的Angular应用程序发送到Node.js,以发送一个webform到Sendgrid。这工作后,一些变化和感谢很多快速启动。将我的表单数据发送到Sendgrid现在正在工作!
在这个项目中,我使用Angular Fullstack,以便能够在我的Angular应用中使用Node的功能。
然而,这个例子只有输入字段和一个文本区。我希望能够添加一个文件(PDF, Docx,例如),以便人们可以通过Sendgrid发送附件给收件人。我已经寻找了一个解决方案,但找不到一个工作的例子。也许因为我不可能达到我想达到的目标。
MY VIEW (CLIENT):
<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 (CLIENT):
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");
})
};
});
MY APP.JS (SERVER):
'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;
有两个主要问题:
- 客户端:我如何在这个表单中发布从Angular到Node的附件?我必须先上传文件,还是我可以用$http.post将其发送到Node ?或者我必须使用ng-file-upload? 服务器端:我如何发送附件到Sendgrid/Nodemailer。从服务器上的app.js发送硬编码文件到Sendgrid不起作用。邮件已成功发送到Sendgrid,但未包含附件。
提前感谢!
上传一个带有angular表单的文件
您遇到的第一个问题是ng-model
不能与<input type="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]);
});
});
}
};
}]);
然后在你的文件输入元素上使用这样的指令:
<input type="file" file-model="email.attachment" ng-required="true" id="email-attachment" name="attachment" class="form-control" />
注意,我将email.file
改为email.attachment
,以避免在其余代码中混淆。
接下来,需要在AJAX请求中包含该文件。您将需要使用FormData
。使用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()
。这是为了防止angular解析FormData
对象并设置内容类型。
这部分的答案很大程度上依赖于这篇博客文章。
2。使用Nodemailer发送附件
要以express方式访问文件,请使用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的自述部分关于电子邮件字段,它说使用attachments
属性是一个数组的attachment
对象。
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);
});
});
上面的示例将附件保存在内存中,如果频繁上传大文件,这可能会很糟糕。您可以将文件写入磁盘:
var upload = multer({ dest: '/uploads' });
然后,不是将文件的buffer
设置为附件的content
,而是将附件的path
设置为文件的path
:
attachments: [
{
filename: req.file.originalname,
path: req.file.path
}
]
多亏了gilly3,我终于完成了这项工作。我不得不对他的代码做一个小小的改动。在控制器中,我更改了:
formData.set(key, $scope.email[key]);
到以下代码:
formData.append(key, $scope.email[key]);
- Node.js v6.2.0类扩展不是函数错误
- 如何使用 node.js 比较两个 json 数组
- Node.js's Buffer.writeFloatBE in Javascript
- node.js:setInterval()正在跳过调用
- 如何处理node.js节点mongodb中的连接和查询队列
- Node.js正在更改应用程序以使用集群模块
- 如何使用Node.js最有效地解析网页
- 在openshift node js应用程序中获取请求
- 正在删除node.js中已验证的网站
- 与运行长作业(javascript,node.js)的第三方API同步的最佳实践
- 在索引.html和应用.js [node.js] 之间共享变量
- Node.js中的JavaScript原型对象效率
- node.js请求数据事件未在CORS ajax调用中触发
- 使用node.js制作网站
- 使用node.js服务器中的evernote api获取note内容
- 有没有任何方法可以使用node-js从不同的机器打开浏览器
- 使用CI和CodeDeploy对node.js应用程序进行连续部署
- 在Node.js中上传和检索图像
- 什么's本地node.js服务器和python简单http服务器之间的区别
- 如何使用 Node JS 获取 JSON 嵌套数组值