Next.js API路由如何正确返回静态文件(如图片)?

Mr-翌钊 阅读 22

我在Next.js项目里用API路由想返回public目录里的图片文件,但返回的是404或者损坏的图片,这是哪里出问题了?

我尝试这样写路由代码:

export default function handler(req, res) {
  const filePath = '/public/images/avatar.jpg';
  res.status(200).sendFile(filePath);
}

但控制台报错说”Path /public/images/avatar.jpg is not under root dir”,明明文件存在啊,是不是路径写法有问题?

我来解答 赞 7 收藏
二维码
手机扫码查看
1 条解答
轩辕浩奇
你遇到的问题是因为 Next.js 的 API 路由中不能直接通过 public 目录的路径去读取文件。Next.js 的 public 目录是设计为静态资源访问的,比如你放了一个 avatar.jpgpublic/images/ 下,访问路径应是 /images/avatar.jpg,不需要通过 API 路由。

你当前用 sendFile 的方式是错误地试图从文件系统读取 /public/... 路径下的内容,但 Next.js 的 API 路由是运行在服务端的 Node.js 环境中,它不能直接访问 public 目录作为文件系统路径,因为构建后的 public 文件会被复制到输出目录(.next),而不是保留原结构。

### 正确做法

如果你只是想返回一张静态图片,**最简单直接的做法是直接返回 302 重定向或使用静态路径**,比如:

export default function handler(req, res) {
res.redirect('/images/avatar.jpg');
}


或者,如果你坚持要通过 API 路由来读取文件内容再返回,推荐的做法是:

1. 把图片文件放在项目根目录外的某个路径下(比如单独建一个 static 文件夹)
2. 使用 Node.js 的 fspath 模块来读取文件并返回内容

示例代码如下:

import fs from 'fs';
import path from 'path';
import { promisify } from 'util';

const readFile = promisify(fs.readFile);

export default async function handler(req, res) {
const imagePath = path.resolve('./static/images/avatar.jpg'); // 注意这个路径要真实存在
try {
const image = await readFile(imagePath);
res.setHeader('Content-Type', 'image/jpeg');
res.status(200).send(image);
} catch (err) {
res.status(500).send('Image not found');
}
}


这样你就可以在 API 路由中灵活返回文件内容,但注意:这并不是推荐的做法,除非你有特殊需求(比如需要权限校验、记录访问日志等)。

总结:对于静态文件,建议直接放在 public 目录下并通过 /images/avatar.jpg 这样的路径直接访问,不要走 API 路由。
点赞 5
2026-02-03 20:00