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

Next.js App Router中服务端与客户端组件环境变量及函数调用问题

解决Next.js App Router中Server Action调用时环境变量undefined及类型不匹配问题

核心问题分析

你遇到的process.env.EMAIL_ADMIN_QUOTE_RECEIVER在浏览器中显示undefined,本质是环境变量未在服务端正确加载或错误地在客户端代码中引用了服务端环境变量。另外,sendEmail函数的类型约束要求toEmail为string,需要从环境变量校验、客户端参数校验两个层面解决。

解决方案步骤

1. 正确配置服务端环境变量

Next.js中,服务端专用的环境变量不需要添加NEXT_PUBLIC_前缀,确保根目录下的.env文件配置正确:

EMAIL=your-gmail-address@gmail.com
EMAIL_PASSWORD=your-app-password
EMAIL_ADMIN_QUOTE_RECEIVER=admin@example.com
  • 配置完成后重启Next.js开发服务器(环境变量修改后需重启生效)。
  • 不要给EMAIL_ADMIN_QUOTE_RECEIVER加NEXT_PUBLIC_前缀,避免暴露给客户端。

2. 强化Server Action的类型安全与环境变量校验

修改sendEmail函数,添加环境变量非空校验,确保运行时不会出现undefined,同时满足TypeScript类型约束:

'use server'
import nodemailer from 'nodemailer';

// 校验所有必要服务端环境变量
const requiredEnvVars = {
  EMAIL: process.env.EMAIL,
  EMAIL_PASSWORD: process.env.EMAIL_PASSWORD,
  EMAIL_ADMIN_QUOTE_RECEIVER: process.env.EMAIL_ADMIN_QUOTE_RECEIVER,
};

Object.entries(requiredEnvVars).forEach(([key, value]) => {
  if (!value) {
    throw new Error(`环境变量 ${key} 未配置,请检查.env文件`);
  }
});

const transporter = nodemailer.createTransport({
  service: 'gmail',
  secure: false,
  auth: {
    user: requiredEnvVars.EMAIL,
    pass: requiredEnvVars.EMAIL_PASSWORD,
  },
});

export const sendEmail = async (toEmail: string, subject: string, html: string) => {
  // 额外校验客户端传递的toEmail参数合法性
  if (!toEmail || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(toEmail)) {
    throw new Error('请提供有效的收件邮箱地址');
  }

  await transporter.sendMail({
    from: requiredEnvVars.EMAIL_ADMIN_QUOTE_RECEIVER,
    to: toEmail,
    subject: subject,
    html: html
  });
};

3. 客户端组件调用时的参数校验

在客户端组件的handleSendQuote函数中,确保传递给sendEmail的toEmail是合法string类型:

'use client'
import { sendEmail } from '@/path/to/your/server-action-file';

const handleSendQuote = async (formData: FormData) => {
  // 从表单获取参数并做类型转换与校验
  const toEmail = formData.get('toEmail')?.trim();
  const subject = formData.get('subject')?.trim() || '默认主题';
  const html = formData.get('html')?.trim() || '<p>默认内容</p>';

  // 校验toEmail是否为有效字符串
  if (typeof toEmail !== 'string' || !toEmail) {
    alert('请输入有效的收件邮箱');
    return;
  }

  try {
    await sendEmail(toEmail, subject, html);
    alert('邮件发送成功');
  } catch (error) {
    console.error('邮件发送失败:', error);
    alert('邮件发送失败,请稍后重试');
  }
};

关键注意事项

  • Server Action中的代码完全运行在服务端,客户端无法直接访问其中的环境变量,你之前在浏览器中看到的undefined,大概率是不小心在客户端组件中直接引用了process.env.EMAIL_ADMIN_QUOTE_RECEIVER,请检查客户端代码并移除这类引用。
  • 若使用Gmail服务,需确保开启应用专用密码(启用两步验证时),否则会出现认证失败问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:15