SWR返回空字符串问题:Webhook数据无法被前端正常获取
问题分析与解决方案
核心问题原因
你遇到的问题主要来自两点:
- API路由请求方法不匹配:你的
/api/job路由只处理了Webhook的POST请求,但SWR默认发送的是GET请求。如果路由没实现GET逻辑,自然会返回空字符串。 - 数据未持久化:Next.js的API路由是无状态的,Webhook回调的数据仅存在当前请求的内存中,请求结束后就会被释放。后续SWR的GET请求根本拿不到留存的数据。
必须存储响应数据
是的,必须把Webhook回调的数据持久化存储,才能让前端通过SWR反复获取。根据项目规模可以选这些方案:
- 小型项目:本地文件、Redis
- 中大型项目:PostgreSQL/MySQL等数据库
具体实现步骤(以文件存储+动态路由为例)
1. 改造API路由(按任务ID区分)
创建/pages/api/job/[id].js,同时处理POST(接收Webhook)和GET(返回存储的数据):
import fs from 'fs/promises'; import path from 'path'; export default async function handler(req, res) { const { id } = req.query; const dataDir = path.join(process.cwd(), 'job-data'); // 确保存储目录存在 await fs.mkdir(dataDir, { recursive: true }); if (req.method === 'POST') { // 接收Webhook的任务结果 const jobResult = req.body; // 以任务ID为文件名存储结果 await fs.writeFile(path.join(dataDir, `${id}.json`), JSON.stringify(jobResult)); res.status(200).json({ success: true }); } else if (req.method === 'GET') { // 处理SWR的GET请求,返回存储的结果 try { const content = await fs.readFile(path.join(dataDir, `${id}.json`), 'utf8'); res.status(200).json(JSON.parse(content)); } catch (err) { // 任务未完成或不存在时返回提示 res.status(404).json({ msg: '任务未完成或不存在' }); } } else { res.setHeader('Allow', ['GET', 'POST']); res.status(405).end(`Method ${req.method} Not Allowed`); } }
2. 前端上传与SWR请求逻辑
上传文件时生成唯一任务ID,传给外部API(让Webhook回调时带回该ID),再用SWR轮询获取结果:
import { v4 as uuidv4 } from 'uuid'; import useSWR from 'swr'; // 上传文件并获取任务ID async function uploadFile(file) { const jobId = uuidv4(); const formData = new FormData(); formData.append('file', file); formData.append('jobId', jobId); // 把任务ID传给外部API await fetch('https://你的外部API地址/upload', { method: 'POST', body: formData, }); return jobId; } // 展示任务结果的组件 function JobResult({ jobId }) { // 每3秒轮询一次,直到拿到结果 const { data, error } = useSWR(`/api/job/${jobId}`, { refreshInterval: 3000 }); if (error) return <div>获取结果失败</div>; if (!data || data.msg) return <div>任务处理中...</div>; return <div>任务结果:{JSON.stringify(data)}</div>; }
3. 外部API回调配置
确保外部API回调时,请求地址是你的Next.js项目的/api/job/[任务ID],并以POST方法发送结果数据。
额外注意事项
- 任务ID要唯一:用UUID生成,避免多个任务数据互相覆盖。
- 清理过期数据:定期删除已完成任务的存储文件/记录,避免占用过多空间。
- 数据校验:在Webhook接收逻辑里添加校验,防止无效数据存入。
内容的提问来源于stack exchange,提问作者Ilir
相关产品推荐
相关产品推荐

