基于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
相关产品推荐
相关产品推荐

