
在 next.js 中,客户端组件无法通过 `export/import` 直接向服务端 api 路由共享状态;必须通过 http 请求(如 `fetch` post)发送数据,服务端再从 `req.body` 解析——这是前后端分离架构的基本约束。
为什么 export let formData 在 API 中无效?
根本原因在于执行环境隔离:
- FormComponent 运行在浏览器(客户端),其 formData 是内存中的 JavaScript 变量;
- /api/endpoint 是服务端 Node.js 函数(API Route),启动时独立于任何前端组件,也无法访问客户端内存。
因此,import { formData } from './FormComponent' 在服务端会得到 undefined ——它导入的是模块顶层声明的初始空对象,而非用户提交后的动态值。
✅ 正确做法:用 fetch 发起 POST 请求
修改表单组件,移除全局可变 export let formData,改用受控组件 + fetch 显式提交:
// components/FormComponent.tsx
import { useState } from 'react';
const FormComponent = () => {
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
const handleChange = (e: React.ChangeEvent) => {
setFormData(prev => ({
...prev,
[e.target.name]: e.target.value,
}));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
const res = await fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const result = await res.json();
console.log('Submission successful:', result);
alert('Message sent!');
} catch (err) {
console.error('Submission failed:', err);
alert('Failed to send. Please try again.');
}
};
return (
);
};
export default FormComponent; ? 对应的 API 路由(服务端接收)
创建文件 pages/api/submit.ts(或 app/api/submit/route.ts,取决于你使用 Pages Router 还是 App Router):
// pages/api/submit.ts
export default async function handler(req, res) {
// ✅ 必须处理 POST 方法
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' });
}
try {
// 解析请求体(Next.js 默认不自动解析 JSON)
let body;
try {
body = JSON.parse(req.body);
} catch (e) {
return res.status(400).json({ error: 'Invalid JSON' });
}
// ✅ 现在可以安全访问表单字段
console.log('Received data:', body);
console.log('Email:', body.email); // 例如:body.email
// ? 此处可调用数据库、邮件服务等
// await sendEmail(body.email, body.message);
res.status(200).json({
success: true,
received: { email: body.email, name: body.name }
});
} catch (error) {
console.error('API error:', error);
res.status(500).json({ error: 'Internal server error' });
}
}? 重要提示(App Router 用户):若使用 app/api/submit/route.ts,需改为:export async function POST(request: Request) { const body = await request.json(); // ✅ 自动解析 JSON console.log(body); return Response.json({ success: true }); }
⚠️ 常见陷阱与最佳实践
- 不要依赖全局变量跨环境通信:export let 仅适用于同环境模块复用(如多个客户端组件),对服务端无效。
- 始终校验请求方法和数据格式:API 路由可能被任意客户端调用,务必检查 req.method 和 JSON.parse 异常。
- 启用 CORS(如需跨域):开发时若前端与 API 域名不同,需在 API 中添加响应头(Next.js 默认允许同域)。
- 敏感操作加服务端验证:邮箱格式、长度、防注入等逻辑不可仅依赖前端,必须在 API 中二次校验。
通过 fetch 显式传递数据,既符合 Web 架构规范,也确保了安全性与可维护性——这才是 Next.js 全栈开发的正确范式。











