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

Next.js 14服务器端动作中能否用原生fetch发送multipart/form-data请求?

Next.js 14服务器端动作中fetch API替代方案解答

1. 继续使用node-fetch没必要

Next.js 14的服务器端已经完全兼容原生Web fetch API,还做了针对性扩展——比如自动缓存、请求重试、适配App Router的特性。现在Node.js环境本身也原生支持fetch和FormData,额外引入node-fetch只会增加项目依赖体积,完全没有必要。原生fetch和Next.js框架的集成度更高,能更好利用框架提供的Edge Runtime支持、缓存策略配置等功能。

2. 完全可以用原生fetch替代node-fetch和form-data

原生Web API的FormData已经能在Next.js服务器端直接使用,配合fetch就能实现multipart/form-data格式的文件上传,不需要依赖第三方库。

示例代码(客户端传文件到服务器端动作)

// app/actions/upload.ts
'use server';

export async function uploadFileAction(file: File) {
  const formData = new FormData();
  formData.append('file', file);
  formData.append('meta', '来自Next.js服务器端的上传请求');

  try {
    const res = await fetch('https://你的外部端点地址', {
      method: 'POST',
      body: formData,
      // 无需手动设置Content-Type,fetch会自动生成带boundary的正确请求头
    });

    if (!res.ok) throw new Error(`请求失败: ${res.status}`);
    return await res.json();
  } catch (err) {
    console.error('上传出错:', err);
    throw err;
  }
}

服务器端读取本地文件上传的示例

如果是从服务器文件系统读取文件上传,Node.js 18+支持直接使用File构造函数:

'use server';
import fs from 'fs';
import path from 'path';

export async function uploadLocalFile() {
  const filePath = path.join(process.cwd(), 'public', 'demo.png');
  const fileBuffer = fs.readFileSync(filePath);
  // 用文件缓冲区创建File对象
  const localFile = new File([fileBuffer], 'demo.png', { type: 'image/png' });

  const formData = new FormData();
  formData.append('file', localFile);

  const res = await fetch('https://你的外部端点地址', {
    method: 'POST',
    body: formData,
  });

  return res.ok ? await res.json() : new Error('上传失败');
}

关键注意点

  • 不要手动设置Content-Type:当请求body是FormData实例时,fetch会自动生成包含正确boundary的multipart/form-data请求头,手动设置反而可能导致边界不匹配,上传失败。
  • Node.js版本兼容:Next.js 14要求Node.js 18.17+,这个版本已经完全支持原生fetch和FormData API,无需担心兼容性问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:37:11