嵌套Fetch+Async流程报错:Response body stream已读取问题求助
问题分析与修复方案
问题根源
你遇到的错误Failed to execute 'json' on 'Response': body stream already read,核心原因是:
- Fetch API返回的
Response对象的响应体是一次性可读流,调用json()、text()这类方法时会读取并消耗整个流。 - 你在
console.log(response: ${response.json()})里先调用了一次response.json(),已经把流读完了,后续再执行const session = await response.json()时,流已经被关闭,自然报错。
违反的规则
Fetch API的Response body流设计为单次消费,这是浏览器为优化内存使用的机制——一旦流被读取完成,就会释放相关资源,不允许重复读取。
修复代码
把response.json()的结果先存到变量中,再复用这个变量,避免多次读取流:
const signUp = (e) => { e.preventDefault(); if (password === passwordConfirmation) { axios .post( "/api/auth/signup/", { email, password, passwordConfirmation }, { headers: { "Content-Type": "application/json", }, withCredentials: true, } ) .then((res) => { const data = res.data; setUser(data.user); // Set the error message if (data.message.status === "error") { console.log("Error present"); setMessage(data.message); } return data.message.status; }) .then(async (serverMessage) => { // On successful sigin, redirect to /api/stripe/checkout-session/ if (serverMessage !== "error") { // Get Stripe.js instance const stripe = await stripePromise; const response = await fetch("/api/stripe/checkout-session/", { method: "POST", }); // 先读取一次响应并保存到变量 const sessionData = await response.json(); console.log(`response:`, sessionData); // 直接打印变量 console.log(`session:`, sessionData); // When the customer clicks on the button, redirect them to Checkout. const result = await stripe.redirectToCheckout({ sessionId: sessionData.sessionId, }); } }) .catch((err) => { console.log(err); console.log(err.request); console.log(err.message); }); } else { setMessage({ status: "error", body: "Passwords do not match. Please try again.", }); } };
关键修改点
- 移除了直接在
console.log中调用response.json()的代码,改为先将响应数据存入sessionData变量 - 后续的日志打印和Stripe跳转逻辑都复用
sessionData变量,不再重复读取响应流
内容的提问来源于stack exchange,提问作者cphill
相关产品推荐
相关产品推荐

