调用response.text()报错:body stream already read的原因及解决方法
错误含义与修复方案
错误含义
Uncaught (in promise) TypeError: Failed to execute 'text' on 'Response': body stream already read 这个错误表示:你尝试读取的Response对象的body流已经被消耗完毕。浏览器中Response对象的body是一次性可读流,一旦调用text()、json()这类读取流的方法,整个流就会被清空,无法再次读取。
修复方案
你的代码核心问题在于,Promise.all返回的是Response对象数组,若后续存在重复读取该Response流的操作(比如误多次调用text()),就会触发这个错误。最直接高效的修复方式是在fetch阶段就把Response转换成文本的Promise,让Promise.all直接等待所有文本内容就绪:
var responses = []; for(const [key, value] of Object.entries(links)){ // 直接将fetch后获取文本的Promise加入数组 let textPromise = fetch('https://api.codetabs.com/v1/proxy?quest='+value) .then(response => response.text()); responses.push(textPromise); } Promise.all(responses) .then(htmlContents => { htmlContents.forEach(content => { processhtmldata(content); // 直接传入文本内容处理 }); }) .catch(err => { console.error('请求或解析失败:', err); });
如果你的业务逻辑需要保留Response对象(比如要读取状态码、响应头),可以通过克隆Response对象来避免原流被消耗:
var responses = []; for(const [key,value] of Object.entries(links)){ let resp = fetch('https://api.codetabs.com/v1/proxy?quest='+value); responses.push(resp); } Promise.all(responses) .then(htmlfiles => { htmlfiles.forEach(file => { // 克隆Response后读取文本,原Response的流不会被消耗 file.clone().text().then(data => { processhtmldata(data); }); }) })
内容的提问来源于stack exchange,提问作者user19835820
相关产品推荐
相关产品推荐

