You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于React前端时间参数,实现NodeJS定时发送邮件

问题:使用node-schedule处理前端传入的日期时间实现定时发送邮件失败

背景

我有一个ReactJS应用,支持用户提交日期、时间及文本内容并提交到NodeJS后端。当前后端实现即时发送邮件的代码如下:

app.post("/send", function (req, res) {
 let mailOptions = {
   from: `${req.body.vals.email}`,
   to: process.env.EMAIL,
   subject: 'SUBJECT INFO',
   html: `${req.body.vals.date} ${req.body.vals.time} ${req.body.vals.info}`,
 };


 transporter.sendMail(mailOptions, function (err, data) {
   if (err) {
     res.json({
       status: "fail",
     });
   } else {
     console.log("email sent");
     res.json({
       status: "success",
     });
   }
 });
});

需求与问题

希望根据前端传入的指定日期和时间定时发送邮件,使用node-schedule库时,日期时间格式处理出现问题,导致定时任务未生效。

前端传入的日期格式为2022-08-28,时间格式为14:07。

尝试的无效代码

app.post("/send", function (req, res) {
 let mailOptions = {
   from: `${req.body.vals.email}`,
   to: process.env.EMAIL,
   subject: 'SUBJECT INFO',
   html: `${req.body.vals.date} ${req.body.vals.time} ${req.body.vals.info}`,
 };

 const dateParsed = new Date(`${req.body.vals.date}T${req.body.vals.time}Z`)

schedule.scheduleJob(dateParsed, function(){
  transporter.sendMail(mailOptions, function (err, data) {
    if (err) {
      res.json({
        status: "fail",
      });
    } else {
      console.log("email sent");
      res.json({
        status: "success",
      });
      
    }
  });
 })


});

解决方案

1. 修正日期时间解析问题

原代码中直接拼接T${time}Z会将时间解析为UTC时区,若前端传入的是本地时间,会导致定时时间偏差。正确做法是拆分日期时间字段,构建对应时区的Date对象:

// 拆分日期和时间字段
const [year, month, day] = req.body.vals.date.split('-');
const [hour, minute] = req.body.vals.time.split(':');
// 构建本地时间Date对象(注意月份从0开始,需减1)
const scheduledDate = new Date(year, month - 1, day, hour, minute);

2. 修正响应时机问题

原代码在定时任务回调中返回HTTP响应是错误的,因为POST请求的连接会在任务调度完成后就关闭,无法等到定时任务执行。应先返回任务调度成功的响应,再在定时任务内部处理邮件发送结果。

完整修正代码

app.post("/send", function (req, res) {
  const { email, date, time, info } = req.body.vals;
  const mailOptions = {
    from: email,
    to: process.env.EMAIL,
    subject: 'SUBJECT INFO',
    html: `${date} ${time} ${info}`,
  };

  // 解析前端传入的日期时间为本地时间
  const [year, month, day] = date.split('-');
  const [hour, minute] = time.split(':');
  const scheduledDate = new Date(year, month - 1, day, hour, minute);

  // 校验日期有效性
  if (isNaN(scheduledDate.getTime())) {
    return res.json({ status: "fail", message: "无效的日期时间格式" });
  }

  // 调度定时邮件任务
  schedule.scheduleJob(scheduledDate, function(){
    transporter.sendMail(mailOptions, function (err) {
      if (err) {
        console.error("定时邮件发送失败:", err);
      } else {
        console.log("定时邮件发送成功");
      }
    });
  });

  // 立即返回任务创建成功的响应
  res.json({ status: "success", message: "定时邮件任务已创建" });
});

额外注意事项

  • 若服务器使用UTC时区,需将前端本地时间转换为UTC时间后再构建Date对象,避免时差问题。
  • 确保已正确安装依赖:npm install node-schedule
  • 若需服务器重启后保留定时任务,需将任务信息存入数据库,重启时重新加载调度。

内容的提问来源于stack exchange,提问作者helpmepie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 08:03:34