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

在NextJS中使用Resend发送附件失败问题求助

在Next.js API路由/Server Actions中用Resend发送正常附件的解决方案

核心问题分析

你遇到的附件损坏问题,大概率是Base64内容格式错误或文件路径处理不当导致的。Resend对附件的Base64内容有明确要求,且本地文件/URL路径的使用也有规范。

修复方案

1. 处理前端传来的Base64附件(API路由版本)

前端传递的Base64内容通常带有data:[mime-type];base64,前缀,Resend无法识别该前缀,会直接将其作为文件内容的一部分,导致文件损坏。需要在后端移除该前缀:

import { EmailTemplate } from '@/components/EmailTemplate';
import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

export async function POST(req: Request) {
    try {
        const { subject, attachments } = await req.json();

        // 预处理附件:移除Base64前缀,保留纯编码字符串
        const processedAttachments = attachments.map(att => {
            if (att.content?.startsWith('data:')) {
                return {
                    ...att,
                    content: att.content.split(';base64,').pop() || att.content
                };
            }
            return att;
        });

        const { data } = await resend.emails.send({
            from: 'Test Mail <onboarding@resend.dev>',
            to: ['test@email.com'],
            subject,
            react: EmailTemplate() as React.ReactElement,
            attachments: processedAttachments,
        });

        return Response.json(data);
    } catch (error) {
        return Response.json({ error });
    }
}

2. Server Actions版本(支持本地文件/Base64/URL)

如果使用Server Actions,处理本地文件时不要直接传递相对路径,建议读取文件并转换为Base64:

'use server';

import { EmailTemplate } from '@/components/EmailTemplate';
import { Resend } from 'resend';
import fs from 'fs/promises';
import path from 'path';

const resend = new Resend(process.env.RESEND_API_KEY);

export async function sendEmailWithAttachments(subject: string, attachments: Array<{filename: string, content?: string, path?: string}>) {
    try {
        const processedAttachments = await Promise.all(attachments.map(async att => {
            if (att.path) {
                // 读取本地文件并转换为Base64
                const filePath = path.join(process.cwd(), att.path);
                const fileBuffer = await fs.readFile(filePath);
                return {
                    filename: att.filename,
                    content: fileBuffer.toString('base64'),
                    type: att.type // 可选:手动指定MIME类型,比如'application/pdf'
                };
            } else if (att.content?.startsWith('data:')) {
                // 移除Base64前缀
                return {
                    ...att,
                    content: att.content.split(';base64,').pop() || att.content
                };
            }
            return att;
        }));

        const { data } = await resend.emails.send({
            from: 'Test Mail <onboarding@resend.dev>',
            to: ['test@email.com'],
            subject,
            react: EmailTemplate() as React.ReactElement,
            attachments: processedAttachments,
        });

        return data;
    } catch (error) {
        throw error;
    }
}

关键注意事项

  • Base64格式:必须移除data:[mime-type];base64,前缀,仅保留纯编码字符串
  • 本地文件:不要直接传递相对路径,需读取文件转换为Base64或Buffer后传入
  • URL路径:确保使用可公开访问的完整URL(不要用localhost链接,Resend服务器无法访问本地服务)
  • MIME类型:若文件名扩展名无法被正确识别,可手动指定type字段(如type: 'image/png')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 13:22:57