fix api server
This commit is contained in:
107
api/server.js
107
api/server.js
@@ -38,6 +38,25 @@ const transporter = nodemailer.createTransport({
|
||||
user: process.env.EMAIL_USER || '', // 发送方邮箱
|
||||
pass: process.env.EMAIL_PASS || '', // 授权码或密码
|
||||
},
|
||||
// 增加连接超时设置
|
||||
connectionTimeout: 10000, // 10秒连接超时
|
||||
greetingTimeout: 10000, // 10秒问候超时
|
||||
socketTimeout: 15000, // 15秒socket超时
|
||||
// 增加重试选项
|
||||
pool: true, // 使用连接池
|
||||
maxConnections: 5, // 最大连接数
|
||||
maxMessages: 100, // 每个连接最大消息数
|
||||
// 调试选项
|
||||
debug: true, // 启用调试日志
|
||||
});
|
||||
|
||||
// 验证传输器连接
|
||||
transporter.verify(function(error, success) {
|
||||
if (error) {
|
||||
console.error('SMTP连接验证失败:', error);
|
||||
} else {
|
||||
console.log('SMTP服务器连接成功,准备发送邮件');
|
||||
}
|
||||
});
|
||||
|
||||
// 存储IP地址最后发送邮件的时间
|
||||
@@ -72,31 +91,73 @@ app.post('/api/send-email', rateLimitMiddleware, async (req, res) => {
|
||||
return res.status(400).json({ error: '请填写所有必填字段' });
|
||||
}
|
||||
|
||||
try {
|
||||
// 邮件选项
|
||||
const mailOptions = {
|
||||
from: `"个人网站联系表单" <${process.env.EMAIL_USER}>`,
|
||||
to: process.env.EMAIL_RECIPIENT || process.env.EMAIL_USER, // 接收方邮箱
|
||||
subject: subject ? `新的联系表单消息: ${subject}` : '新的联系表单消息',
|
||||
html: `
|
||||
<h3>您有一条新的联系表单消息</h3>
|
||||
<p><strong>姓名:</strong> ${name}</p>
|
||||
<p><strong>邮箱:</strong> ${email}</p>
|
||||
<p><strong>主题:</strong> ${subject || '无'}</p>
|
||||
<p><strong>消息:</strong></p>
|
||||
<p>${message.replace(/\n/g, '<br>')}</p>
|
||||
`,
|
||||
// 回复选项,回复时会发送到表单提交者的邮箱
|
||||
replyTo: email
|
||||
};
|
||||
// 邮件选项
|
||||
const mailOptions = {
|
||||
from: `"个人网站联系表单" <${process.env.EMAIL_USER}>`,
|
||||
to: process.env.EMAIL_RECIPIENT || process.env.EMAIL_USER, // 接收方邮箱
|
||||
subject: subject ? `新的联系表单消息: ${subject}` : '新的联系表单消息',
|
||||
html: `
|
||||
<h3>您有一条新的联系表单消息</h3>
|
||||
<p><strong>姓名:</strong> ${name}</p>
|
||||
<p><strong>邮箱:</strong> ${email}</p>
|
||||
<p><strong>主题:</strong> ${subject || '无'}</p>
|
||||
<p><strong>消息:</strong></p>
|
||||
<p>${message.replace(/\n/g, '<br>')}</p>
|
||||
`,
|
||||
// 回复选项,回复时会发送到表单提交者的邮箱
|
||||
replyTo: email
|
||||
};
|
||||
|
||||
// 发送邮件
|
||||
await transporter.sendMail(mailOptions);
|
||||
|
||||
return res.status(200).json({ success: true, message: '邮件已成功发送' });
|
||||
// 最大重试次数
|
||||
const maxRetries = 3;
|
||||
let retries = 0;
|
||||
let lastError = null;
|
||||
|
||||
// 重试发送邮件的函数
|
||||
const attemptSendMail = async () => {
|
||||
try {
|
||||
const info = await transporter.sendMail(mailOptions);
|
||||
console.log('邮件发送成功:', info.messageId);
|
||||
return true;
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
console.error(`发送邮件失败 (尝试 ${retries + 1}/${maxRetries}):`, error);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
// 尝试发送邮件,最多重试maxRetries次
|
||||
let success = false;
|
||||
while (retries < maxRetries && !success) {
|
||||
success = await attemptSendMail();
|
||||
if (!success) {
|
||||
retries++;
|
||||
if (retries < maxRetries) {
|
||||
// 等待一段时间后重试,每次等待时间增加
|
||||
const waitTime = 1000 * retries; // 1秒, 2秒, 3秒...
|
||||
console.log(`等待 ${waitTime}ms 后重试...`);
|
||||
await new Promise(resolve => setTimeout(resolve, waitTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (success) {
|
||||
return res.status(200).json({ success: true, message: '邮件已成功发送' });
|
||||
} else {
|
||||
// 所有重试都失败了
|
||||
console.error('所有重试都失败,最后一个错误:', lastError);
|
||||
return res.status(500).json({
|
||||
error: '发送邮件失败,请稍后再试',
|
||||
details: lastError ? lastError.message : '未知错误'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('发送邮件时出错:', error);
|
||||
return res.status(500).json({ error: '发送邮件失败,请稍后再试' });
|
||||
console.error('发送邮件过程中出现异常:', error);
|
||||
return res.status(500).json({
|
||||
error: '发送邮件过程中出现异常',
|
||||
details: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user