为何使用node-fetch与Node.js内置fetch发起API请求返回结果不同?
问题
我有一个Node.js应用,会向Manifold(模拟博彩网站)发送API请求触发下注。用node-fetch时能成功下注;但用Node.js内置fetch时,如果存在旧下注记录,接口会返回旧的下注信息(怀疑是HTTP响应被缓存了),而且重启Node.js服务器也没用,还是返回旧响应。除了注释/取消注释第3行的node-fetch导入语句,代码完全没改。用Postman发相同请求则能成功下注。
相关代码(api/placebet/routes.ts)
import { NextResponse } from 'next/server'; import fetch from 'node-fetch'; export async function POST(request: Request) { const body = await request.json(); const sendTime = Date.now(); console.log('placeBet called with body:', body.apiKey, body.betAmount, body.outcomeToBuy, body.marketID); const res = await fetch('https://manifold.markets/api/v0/bet', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Key ${body.apiKey}`, }, body: JSON.stringify({ amount: body.betAmount, outcome: body.outcomeToBuy, contractId: body.marketID, }), }); if (!res.ok) { const errorDetails = await res.json(); console.error(errorDetails); return NextResponse.json({error: "Error placing the bet"}, {status: 500 }); } const data = await res.json(); // 检查下注时间戳是否早于请求发送时间 const betTimestamp = data.fills[0].timestamp; if (betTimestamp < sendTime) { console.error('Error: Bet timestamp is before sendTime'); console.log(data); return NextResponse.json({error: "Bet timestamp is before sendTime"}, {status: 500 }); } console.log("Bet response", data) return NextResponse.json(data) }
可能的原因与解决办法
- 内置fetch缓存策略差异:Node.js内置
fetch(v18+支持)默认可能对响应启用了缓存逻辑,而node-fetch无此默认行为。尽管POST请求通常不会被缓存,但部分服务器或中间件可能存在异常处理。 - 强制禁用缓存:在请求头中添加缓存控制字段,明确要求不使用缓存:
const res = await fetch('https://manifold.markets/api/v0/bet', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Key ${body.apiKey}`, 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' }, // 其他配置不变 }); - 添加唯一请求标识:在URL后追加时间戳参数,确保每次请求都是唯一的,避免被中间层缓存:
const url = `https://manifold.markets/api/v0/bet?ts=${Date.now()}`; const res = await fetch(url, { /* 原有配置不变 */ }); - 禁用Next.js路由缓存:如果使用Next.js App Router,路由处理函数可能被默认缓存。在路由文件顶部添加配置,强制每次请求都执行逻辑:
export const dynamic = 'force-dynamic'; // 新增此行 import { NextResponse } from 'next/server'; // 其他代码不变
内容的提问来源于stack exchange,提问作者NYoung
相关产品推荐
相关产品推荐

