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

基于Amplify SSR的Next.js应用:API返回重复数据——缓存问题?

Next.js(App Router+SSR)部署在Amplify后,S3上传图片无法实时更新列表的排查方案

我在AWS Amplify上部署了采用App Router与SSR模式的Next.js应用,功能是展示S3存储桶中的图片,同时支持用户上传新图片到S3。预期上传完成后调用API实时更新图片列表,但实际API始终返回旧数据,新增图片无法同步显示。已经尝试在API中设置Cache-Control: no-store,但问题依然存在。

以下是api/list/route.tsx的源代码:

import { S3Client, ListObjectsV2Command } from '@aws-sdk/client-s3';
import { NextResponse } from 'next/server';

const s3 = new S3Client({
  region: process.env.NEXT_PUBLIC_AWS_REGION!,
  credentials: {
    accessKeyId: process.env.NEXT_PUBLIC_AWS_ACCESS_KEY_ID!,
    secretAccessKey: process.env.NEXT_PUBLIC_AWS_SECRET_ACCESS_KEY!,
  },
});

export async function GET() {
  const headers = new Headers();
  headers.set('Cache-Control', 'no-store'); // 禁用缓存

  try {
    const command = new ListObjectsV2Command({
      Bucket: process.env.NEXT_PUBLIC_AWS_S3_BUCKET!,
    });

    const { Contents } = await s3.send(command);

    const files =
      Contents?.map((file) => ({
        key: file.Key!,
        lastModified: file.LastModified!,
        size: file.Size!,
        url: `https://${process.env.NEXT_PUBLIC_AWS_S3_BUCKET}.s3.${process.env.NEXT_PUBLIC_AWS_REGION}.amazonaws.com/${file.Key}`,
      })) || [];

    return NextResponse.json(files);
  } catch (error) {
    console.error('Error fetching S3 objects:', error);
    return NextResponse.json({ error: 'Failed to fetch S3 objects' }, { status: 500 });
  }
}

排查方向与解决建议

1. 检查Amplify边缘缓存配置

Amplify部署Next.js时,CDN边缘节点可能会忽略代码中的Cache-Control头,自行缓存API响应:

  • 进入Amplify控制台,找到目标应用的App settings > Hosting > Rewrites and redirects,查看是否有针对/api/*路由的自定义缓存规则,确保规则设置为不缓存。
  • 在Hosting > Cache management中,为/api/list路由单独配置缓存行为,将缓存策略设为no-store或no-cache。

2. 处理S3列表的最终一致性问题

S3的ListObjectsV2操作是最终一致性的,新上传的对象可能不会立即出现在列表中:

  • 上传完成后延迟200-500ms再调用列表API,或者前端轮询API直到新对象出现。
  • 改用S3事件通知+数据库同步方案:配置S3上传事件触发Lambda,将新对象元数据写入DynamoDB,API直接从数据库读取数据,绕开S3列表的一致性延迟。

3. 强制Next.js API路由动态渲染

App Router中即使是SSR路由,也可能被服务器端缓存,需显式禁用:

  • 在API路由文件顶部添加动态渲染配置:
    export const dynamic = 'force-dynamic'; // 强制每次请求都重新执行
    
  • 前端调用API时,显式设置不缓存:
    const res = await fetch('/api/list', { cache: 'no-store' });
    

4. 验证IAM权限与S3桶配置

排除权限问题导致无法读取新对象:

  • 检查API使用的IAM用户是否拥有s3:ListBucket权限,且S3桶策略没有拒绝该用户访问新上传的对象。
  • 通过S3控制台确认新上传的图片确实存在于目标桶中。

5. 清理Amplify构建缓存

Amplify构建时的缓存可能导致旧代码未更新:

  • 在Amplify部署历史中选择最近的部署,点击Redeploy this version并勾选Clear cache,重新构建部署应用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:43:19