从ReadableStream对象检索数据?

如何从ReadableStream对象中获取信息?

我使用的取回API,我没有看到这是清楚的从文档。

主体作为ReadableStream返回,我只想访问此流中的属性。在浏览器开发工具的Response下,我似乎以JavaScript对象的形式将这些信息组织成属性。

fetch('http://192.168.5.6:2000/api/car', obj)
.then((res) => {
if(!res.ok) {
console.log("Failure:" + res.statusText);
throw new Error('HTTP ' + res.status);
} else {
console.log("Success :" + res.statusText);
return res.body // what gives?
}
})
284128 次浏览

为了从ReadableStream中访问数据,你需要调用其中一个转换方法(docs available 在这里)。

举个例子:

fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
// The response is a Response instance.
// You parse the data into a useable format using `.json()`
return response.json();
}).then(function(data) {
// `data` is the parsed version of the JSON returned from the above endpoint.
console.log(data);  // { "userId": 1, "id": 1, "title": "...", "body": "..." }
});

编辑:如果你的数据返回类型不是JSON或者你不想要JSON,那么使用text()

举个例子:

fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
return response.text();
}).then(function(data) {
console.log(data); // this will be a string
});

希望这能帮你理清思路。

response.json()返回一个Promise。试一试……

res.json().then(body => console.log(body));

其中responsefetch(...)

有些人可能会发现async的例子很有用:

var response = await fetch("https://httpbin.org/ip");
var body = await response.json(); // .json() is asynchronous and therefore must be awaited

json()将响应体从ReadableStream转换为json对象。

await语句必须被包装在async函数中,但是你可以直接在Chrome的控制台中运行await语句(从版本62开始)。

有点晚了,但在使用Sharepoint框架从Odata $批处理请求生成的ReadableStream中获得有用的东西时遇到了一些问题。

与OP有类似的问题,但在我的情况下的解决方案是使用不同于.json()的转换方法。在我的情况下,.text()工作就像一个魅力。然而,为了从文本文件中获得一些有用的JSON,需要进行一些修改。

如果你只想要响应作为文本,不想将其转换为JSON,使用https://developer.mozilla.org/en-US/docs/Web/API/Body/text,然后使用then它来获得承诺的实际结果:

fetch('city-market.md')
.then(function(response) {
response.text().then((s) => console.log(s));
});

fetch('city-market.md')
.then(function(response) {
return response.text();
})
.then(function(myText) {
console.log(myText);
});

我不喜欢用锁链。第二个人就无法获得地位。如前所述,'response.json()'返回一个承诺。返回'response.json()'的then结果,动作类似于第二个then。它还有一个额外的好处,就是在响应范围内。

return fetch(url, params).then(response => {
return response.json().then(body => {
if (response.status === 200) {
return body
} else {
throw body
}
})
})

注意,你只能读取一个流一次,所以在某些情况下,你可能需要克隆响应来重复读取它:

fetch('example.json')
.then(res=>res.clone().json())
.then( json => console.log(json))


fetch('url_that_returns_text')
.then(res=>res.clone().text())
.then( text => console.log(text))

在阅读下一篇文章之前,我有同样的问题超过12个小时,只是为了帮助任何人。当在你的_api页面中使用nextjs时,你需要使用json .stringify(whole-response),然后使用res.send(json .stringify(whole-response))将它发送回你的页面,当它在客户端收到时,你需要将它翻译回json格式,以便它可用。这可以通过阅读它们的序列化部分来计算。希望能有所帮助。

你可能问了一个错误的问题来解决你的问题,但这里有一个对你实际问题的答案。灵感可能来自Node.js stream/consumers模块. js的源代码。

res.body是一个ReadableStream,它释放块作为Uint8Arrays。下面的函数将收集单个Uint8Array中的所有块:

export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
let result = new Uint8Array(0);
const reader = stream.getReader();
while (true) { // eslint-disable-line no-constant-condition
const { done, value } = await reader.read();
if (done) {
break;
}


const newResult = new Uint8Array(result.length + value.length);
newResult.set(result);
newResult.set(value, result.length);
result = newResult;
}
return result;
}

然后可以使用TextDecoder将数组转换为字符串。然后你可以使用JSON.parse()解析这个字符串:

const buffer = await streamToArrayBuffer(res.body);
const text = new TextDecoder().decode(buffer);
const json = JSON.parse(text);

将来当浏览器支持它时,你还可以使用TextDecoderStream直接将流内容收集为字符串:

export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
let result = '';
const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
while (true) { // eslint-disable-line no-constant-condition
const { done, value } = await reader.read();
if (done) {
break;
}


result += value;
}
return result;
}

对于那些拥有ReadableStream并希望从中获取文本的人来说,一个简短的技巧是将其包装在一个新的Response(或Request)中,然后使用text方法:

let text = await new Response(yourReadableStream).text();

你可以在浏览器控制台中测试它是否有效:

// use a Request to hackily/quickly create a readable stream with the text "hello":
let readableStream = new Request("", {method:"POST", body:"hello"}).body;
// wrap it in a `Response` and use the .text() method:
let text = await new Response(readableStream).text();
console.log(text); // outputs "hello"