const express = require('express'); const bodyParser = require('body-parser'); const cors = require('cors'); const nodemailer = require('nodemailer'); const dotenv = require('dotenv'); // 加载环境变量 dotenv.config(); const app = express(); const port = process.env.PORT || 3001; // 中间件 app.use(cors({ origin: '*', // 允许所有来源访问 methods: ['GET', 'POST', 'OPTIONS'], // 允许的HTTP方法 allowedHeaders: ['Content-Type', 'Authorization'], // 允许的请求头 credentials: true // 允许发送凭证 })); app.use(bodyParser.json()); // 处理OPTIONS预检请求 app.options('*', (req, res) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization'); res.header('Access-Control-Max-Age', '86400'); // 24小时 res.sendStatus(204); }); // 创建Nodemailer传输器 const transporter = nodemailer.createTransport({ service: process.env.EMAIL_SERVICE || 'smtp', // 邮件服务商,例如:'gmail', 'qq', '163'等 host: process.env.EMAIL_HOST || 'smtp.163.com', // SMTP服务器 port: parseInt(process.env.EMAIL_PORT || '587'), secure: process.env.EMAIL_SECURE === 'true', // true for 465, false for other ports auth: { user: process.env.EMAIL_USER || '', // 发送方邮箱 pass: process.env.EMAIL_PASS || '', // 授权码或密码 }, }); // 存储IP地址最后发送邮件的时间 const lastEmailSentTime = new Map(); // 速率限制中间件 - 60秒内只能发送一封邮件 const rateLimitMiddleware = (req, res, next) => { const ip = req.ip || req.connection.remoteAddress; const currentTime = Date.now(); const lastTime = lastEmailSentTime.get(ip) || 0; const timeDiff = currentTime - lastTime; // 如果距离上次发送不足60秒,则拒绝请求 if (lastTime && timeDiff < 60000) { const remainingTime = Math.ceil((60000 - timeDiff) / 1000); return res.status(429).json({ error: `请求过于频繁,请在${remainingTime}秒后再试`, remainingTime }); } // 更新最后发送时间并继续处理请求 lastEmailSentTime.set(ip, currentTime); next(); }; // 邮件发送接口 app.post('/api/send-email', rateLimitMiddleware, async (req, res) => { const { name, email, subject, message } = req.body; if (!name || !email || !message) { 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: `

您有一条新的联系表单消息

姓名: ${name}

邮箱: ${email}

主题: ${subject || '无'}

消息:

${message.replace(/\n/g, '
')}

`, // 回复选项,回复时会发送到表单提交者的邮箱 replyTo: email }; // 发送邮件 await transporter.sendMail(mailOptions); return res.status(200).json({ success: true, message: '邮件已成功发送' }); } catch (error) { console.error('发送邮件时出错:', error); return res.status(500).json({ error: '发送邮件失败,请稍后再试' }); } }); // 测试路由 app.get('/api/test', (req, res) => { res.json({ message: 'API服务器运行正常' }); }); // 启动服务器 app.listen(port, () => { console.log(`邮件服务API正在端口 ${port} 上运行`); });