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

Next.js 13 App Router API路由如何读取Public目录静态文件?

Next.js 13 App Router 图片加水印问题解决

针对你在App Router中给上传图片加水印时读取水印文件失败的问题,核心问题出在路径拼接错误和不必要的文件读取操作,以下是具体修正方案:

问题分析

  1. 水印文件路径拼接错误:join(process.cwd(), "/public/wm.png") 里的开头斜杠会导致路径异常,比如Windows系统下会直接指向磁盘根目录的public文件夹,而非项目根目录下的public目录。
  2. 多余的文件读取操作:sharp的composite方法本身支持直接传入文件路径作为input,额外用readFile读取反而容易引发异步或路径类错误。

修正后的代码

// src/app/api/route.ts
import { join } from 'path';
import { writeFile, mkdir } from 'fs/promises';
import sharp from 'sharp';

export async function handleImage(file: File) {
  try {
    const bytes = await file.arrayBuffer();
    const buffer = Buffer.from(bytes);
    const isProduction = process.env.NEXT_PUBLIC_PRODUCTION === 'true';
    let path: string;

    // 确保输出目录存在,避免写入失败
    if (isProduction) {
      path = join('/', 'tmp', file.name);
      await mkdir(join('/', 'tmp'), { recursive: true });
    } else {
      path = join(process.cwd(), 'public', 'tmp', file.name);
      await mkdir(join(process.cwd(), 'public', 'tmp'), { recursive: true });
    }

    // 正确拼接水印文件路径
    const watermarkPath = join(process.cwd(), 'public', 'wm.png');

    // 直接传入水印路径给sharp,无需提前读取文件
    const watermarkedBuffer = await sharp(buffer)
      .composite([{ input: watermarkPath, top: 50, left: 50 }])
      .png({ quality: 80 })
      .toBuffer();

    await writeFile(path, watermarkedBuffer);

    const ImgTwitterId = await rwClient.v1.uploadMedia(path);
    return { path, mediaId: ImgTwitterId };
  } catch (error) {
    console.error('加水印操作失败:', error);
    throw error;
  }
}

关键修改点

  • 路径修正:用join(process.cwd(), 'public', 'wm.png')拼接水印路径,确保开发/生产环境都能正确定位到项目根目录下的public文件夹。
  • 移除多余读取:直接将水印文件路径传入sharp的composite方法,省去readFile步骤,减少出错环节。
  • 目录预创建:添加mkdir并设置recursive: true,确保输出目录存在,避免因目录不存在导致的写入失败。
  • 环境变量判断优化:直接用=== 'true'判断生产环境,避免不必要的类型转换。

额外注意事项

  • 确保已安装sharp依赖:执行npm install sharp或yarn add sharp完成安装。
  • 生产环境中/tmp是临时目录,建议定期清理生成的文件,避免磁盘占用过高。
  • 开发环境下,public目录下的文件会被Next.js静态服务托管,但API路由操作的是本地文件系统,直接操作public目录是可行的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 02:05:21