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

Next.js 14部署环境下上传图片需重启pm2才显示的问题求助

Next.js 14上传图片后无需重启即可显示的解决方案

问题背景

在Ubuntu服务器上部署的Next.js 14应用(搭配Nginx+pm2)遇到以下问题:图片成功上传至public文件夹后,前端无法立即访问,必须执行pm2 restart all重启应用才能显示。已尝试确认文件路径、检查目录权限、刷新客户端缓存,均未解决问题。

核心原因

Next.js生产环境会对public目录的静态资源做预构建和服务端缓存,新增文件不会被自动识别;同时Nginx若配置了静态资源缓存,也会导致旧缓存覆盖新上传的文件。

解决方案

方案1:独立上传目录+Nginx直接代理(推荐)

不要将上传文件存入public目录,而是创建独立的uploads文件夹,让Nginx直接处理该目录的请求,绕过Next.js的服务端缓存。

  1. 创建上传目录并配置权限:
    mkdir /path/to/your/project/uploads
    chmod 755 /path/to/your/project/uploads
    chown www-data:www-data /path/to/your/project/uploads
    
  2. 修改Nginx配置(通常路径为/etc/nginx/sites-available/your-site.conf),在server块中新增:
    location /uploads/ {
      root /path/to/your/project;
      expires -1; # 禁用缓存,或根据需求设置较短缓存时间
      add_header Cache-Control "no-cache, no-store, must-revalidate";
    }
    
  3. 重启Nginx生效:
    sudo nginx -s reload
    

后续上传图片至uploads目录,直接通过https://your-domain/uploads/xxx.jpg访问,无需重启Next.js。

方案2:API路由动态返回图片

若必须使用public目录,可通过API路由动态读取文件,避免Next.js的静态缓存。

在app/api/image/[filename]/route.js创建文件,代码如下:

import fs from 'fs';
import path from 'path';
import { NextResponse } from 'next/server';

export async function GET(request, { params }) {
  const { filename } = params;
  const filePath = path.join(process.cwd(), 'public', filename);

  try {
    if (!fs.existsSync(filePath)) {
      return NextResponse.json({ error: 'File not found' }, { status: 404 });
    }

    const fileBuffer = fs.readFileSync(filePath);
    // 根据文件扩展名设置对应Content-Type
    const ext = path.extname(filename).toLowerCase();
    const contentType = {
      '.png': 'image/png',
      '.jpg': 'image/jpeg',
      '.jpeg': 'image/jpeg',
      '.gif': 'image/gif'
    }[ext] || 'application/octet-stream';

    return new NextResponse(fileBuffer, {
      headers: {
        'Content-Type': contentType,
        'Cache-Control': 'no-cache'
      }
    });
  } catch (err) {
    return NextResponse.json({ error: 'Server error' }, { status: 500 });
  }
}

前端访问图片时使用/api/image/xxx.jpg路径,每次请求都会读取最新的文件。

方案3:禁用Next.js静态资源缓存(不推荐)

此方法会影响应用性能,仅作为临时方案。修改next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'Cache-Control',
            value: 'no-cache, no-store, must-revalidate',
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

修改后需重新构建部署应用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:10:12