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

SWR返回空字符串问题:Webhook数据无法被前端正常获取

问题分析与解决方案

核心问题原因

你遇到的问题主要来自两点:

  1. API路由请求方法不匹配:你的/api/job路由只处理了Webhook的POST请求,但SWR默认发送的是GET请求。如果路由没实现GET逻辑,自然会返回空字符串。
  2. 数据未持久化: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:06:38