使用Nodejs,我已经能够将表单中上传的文件临时存储到某个位置。从那里开始,我想使用mailgun-js
发送附有该文件的电子邮件。
我能够收到电子邮件以显示附件,但附件(在我的测试用例中,我上传普通的png文件)将被破坏。破碎,我的意思是:
我不确定发生了什么 - 但我似乎找不到其他有问题的人;所以我确定我做错了。我感谢任何帮助。
编辑:如果我对路径进行硬编码(即我将图像放在文件夹中,然后将附件设置为该路径),那么它会正确发送附件,我可以查看它没有问题。
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var bodyParser = require('body-parser');
var https = require('https');
var fs = require('fs-extra');
var busboy = require('connect-busboy');
var multer = require('multer');
var app = express();
var upload = multer(({ dest: __dirname + '/tmp/' }));
// view engine setup
app.set('port', (process.env.PORT || 5000));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(favicon(path.join(__dirname,'public','images','favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(busboy());
// Used for accessing webpages without the .html extension!
var publicdir = __dirname + '/public';
app.use(function(req, res, next) {
if (req.path.indexOf('.') === -1) {
var file = publicdir + req.path + '.html';
fs.exists(file, function(exists) {
if (exists)
req.url += '.html';
next();
});
}
else
next();
});
app.use(express.static(publicdir));
//end .html extension removal
var type = upload.single('file');
app.post('/submit', type, function(req, res, next) {
console.log("____ Clicked submit ____");
//whether or not this form will carry an attachment
var hasAttachment = (req.body.attachment == '') ? false : true;
//path of file
var target_path; //actual image
var tmp_path;
var name = req.body.name;
var email = req.body.email;
var subject = req.body.subject;
var message = req.body.message;
//if there is an attachment, handle getting the file
if (hasAttachment) {
tmp_path = req.file.path;
//The original name of the uploaded file stored in the variable target_path
target_path = __dirname + '/tmp/' + req.file.originalname;
//A better way to copy the uploaded file.
var src = fs.createReadStream(tmp_path);
var dest = fs.createWriteStream(target_path);
src.pipe(dest);
}
//Use validator to sanitize for valid emails
var validator = require('validator');
if (!validator.isEmail(email)) {
console.log("Not a valid email");
res.end();
return;
}
//Mailgun api stuff
var api_key = 'redacted';
var domain = 'redacted';
var mailgun = require('mailgun-js')({
apiKey: api_key,
domain: domain
});
//data for mailgun (to, from, name, etc.)
var data;
if (hasAttachment) {
console.log(target_path);
data = {
from: email,
to: 'myEmail@gmail.com',
subject: subject + ' - ' + name,
text: message,
attachment: target_path
};
} else {
data = {
from: email,
to: 'myEmail@gmail.com',
subject: subject + ' - ' + name,
text: message
};
}
console.log(data);
mailgun.messages().send(data, function (error, result) {
if (error) {
console.error(error);
return;
}
});
console.log("Sent an email!!!");
res.redirect('/contact');
//delete the files after sending the email
if (hasAttachment) {
fs.unlink(target_path);
fs.unlink(tmp_path);
}
});
var server = app.listen(app.get('port'), function() {
//nothing
}); //server closing-bracket
/**
* ERROR HANDLING
*/
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
console.error("***ERROR: " + err.message);
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
答案 0 :(得分:1)
send()
是异步的,您在文件有机会完成之前删除该文件。
相反,一旦确定已完成,请删除send
回调中的文件。
<强>更新强>
除了上述内容之外,您的文件副本也是异步发生的,并且您试图在复制完成之前传输文件。所以一定要等到那个:
dest.on("close", function(error, result) {
if (error) {
console.log("COPY ERROR", error);
// TODO: respond with some error result
} else {
mailgun.messages().send(data, function (error, result) {
// delete the files
if (hasAttachment) {
fs.unlink(target_path);
fs.unlink(tmp_path);
}
if (error) {
console.error(error);
// TODO: respond with some error result
} else {
console.log("Sent an email!!!");
res.redirect('/contact');
}
});
}
});
上述更改将使您的代码正常工作。
我认为您正在复制文件,以便图像在电子邮件中正确显示。 (Mailgun根据文件扩展名推断如何处理附件,而Multer的默认临时文件名不包含扩展名。)
您可以通过配置Multer来保留文件扩展名,从而完全避免复制。 https://github.com/expressjs/multer#storage