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

Next.js 14 Server Actions调用第三方API时的CORS问题

解决NextJS中Resend API的CORS错误

问题根源

  • 你将Resend API密钥放在了NEXT_PUBLIC_开头的环境变量中,这会把密钥暴露给客户端,同时导致Resend API请求从浏览器发起,触发CORS限制。
  • Server Action函数未添加'use server'指令,NextJS会默认在客户端执行该函数,而非服务器端。

修复步骤

1. 修正环境变量

在.env.local文件中,修改环境变量的命名,移除NEXT_PUBLIC_前缀(避免敏感信息暴露给客户端):

RESEND_API_KEY=你的Resend API密钥
MY_EMAIL=你的接收邮箱地址

2. 更新Server Action函数

在/app/_actions.ts的sendEmail函数顶部添加'use server'指令,并修正环境变量的读取逻辑:

'use server'; // 必须添加,标记为服务器端执行的Action

import { Resend } from 'resend';

export async function sendEmail({email, name, org, message}: {email: string, name: string, org?: string, message?: string}){
    const resend = new Resend(process.env.RESEND_API_KEY);
    const myEmail = process.env.MY_EMAIL || '';

    try {
        const data = await resend.emails.send({
            from: myEmail,
            to: myEmail,
            subject: `${name}, from ${org || '个人'}`,
            html: `<p>发件人邮箱:${email}</p><p>留言内容:${message || '无'}</p>`
        });    
        return { success: true , data };
    } catch(error) {
        return { success: false , error };
    }
}

3. 修正组件中的调用逻辑

确保组件调用Server Action时遵循NextJS规范,推荐结合表单使用(或用startTransition处理状态):

'use client'; // 客户端组件需添加该指令

import { sendEmail } from './_actions';
import { useTransition } from 'react';

export default function ContactForm() {
    const [isPending, startTransition] = useTransition();

    const submitEmail = async (formData: FormData) => {
        const email = formData.get('email') as string;
        const name = formData.get('name') as string;
        const org = formData.get('org') as string;
        const message = formData.get('message') as string;

        startTransition(async () => {
            const result = await sendEmail({email, name, org, message});
            console.log(result);
            // 这里可添加成功/失败提示逻辑
        });
    };

    return (
        <form action={submitEmail}>
            <input type="email" name="email" required placeholder="你的邮箱" />
            <input type="text" name="name" required placeholder="你的姓名" />
            <input type="text" name="org" placeholder="所属机构" />
            <textarea name="message" placeholder="留言内容" />
            <button type="submit" disabled={isPending}>{isPending ? '发送中...' : '发送'}</button>
        </form>
    );
}

修复原理

  • 'use server'指令强制函数在服务器端执行,Resend API请求会从服务器发起,完全避开浏览器的CORS限制。
  • 移除NEXT_PUBLIC_前缀的环境变量,既保护了敏感的API密钥不被泄露,又能让服务器正常读取配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:27:41