noo*_*oob 98 javascript fetch node.js reactjs
如何从ReadableStream对象获取信息?
我正在使用Fetch API,我没有从文档中看到这一点.
正文作为ReadableStream返回,我只想访问此流中的属性.在浏览器开发工具的响应下,我似乎将这些信息以Javascript对象的形式组织到属性中.
fetch('http://192.168.5.6:2000/api/car', obj)
.then((res) => {
if(res.status == 200) {
console.log("Success :" + res.statusText); //works just fine
}
else if(res.status == 400) {
console.log(JSON.stringify(res.body.json()); //res.body is undefined.
}
return res.json();
})
Run Code Online (Sandbox Code Playgroud)
提前致谢.
Ash*_*son 117
要从ReadableStream您需要调用其中一种转换方法(此处提供的文档)中访问数据.
举个例子:
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": "..." }
});
Run Code Online (Sandbox Code Playgroud)
希望这有助于澄清事情.
Noe*_*oel 33
有些人可能会发现一个async有用的例子:
var response = await fetch("https://httpbin.org/ip");
var body = await response.json(); // .json() is asynchronous and therefore must be awaited
Run Code Online (Sandbox Code Playgroud)
json()将响应的主体从a ReadableStream转换为json对象.
该await语句必须被包裹在一个async功能,但是可以运行await在Chrome的控制台直接语句(如版本62).
cda*_*uth 31
您可能提出了错误的问题来解决您的问题,但这是您实际问题的答案。stream/consumersNode.js模块的源代码可能是一个灵感。
res.body是 a ,它以sReadableStream的形式发出块。请注意,在其他地方创建的对象可能会发出除 之外的其他数据类型,并且在这些情况下需要调整本答案中概述的方法。Uint8ArrayReadableStreamUint8Array
有多种方法可以使用这样的流:
Uint8Arraynew Response(stream).arrayBuffer()如果您想一次性检索流的全部内容,最简单的方法是将其包装在一个Response对象中。然后,您可以使用多种方法之一以字符串、JSON 对象、数组缓冲区或其他形式检索对象。例如,要将其作为数组缓冲区检索:
export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
return new Uint8Array(await new Response(stream).arrayBuffer());
}
Run Code Online (Sandbox Code Playgroud)
请注意,new Response(stream)仅适用于Uint8Array流。如果流发出任何其他类型(例如字符串),则会导致错误TypeError: Received non-Uint8Array chunk。
stream.getReader()以下函数将收集单个块中的所有块Uint8Array:
function concatArrayBuffers(chunks: Uint8Array[]): Uint8Array) {
const result = new Uint8Array(chunks.reduce((a, c) => a + c.length, 0);
let offset = 0;
for (const chunk of chunks) {
result.set(chunk, offset);
offset += chunk.length;
}
return result;
}
export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
const chunks: Uint8Array[] = [];
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
} else {
chunks.push(value);
}
}
return concatArrayBuffers(chunks);
}
Run Code Online (Sandbox Code Playgroud)
ReadableStream实现异步迭代器协议。然而,大多数浏览器尚不支持此功能,但在 Node.js 中您已经可以使用它(使用 TypeScript,您将必须使用该NodeJS.ReadableStream界面,请参阅此讨论)。
以下代码将把所有块收集到一个中Uint8Array:
export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
const chunks: Uint8Array[] = [];
for await (const chunk of stream) {
chunks.push(chunk);
}
return concatArrayBuffers(chunks);
}
Run Code Online (Sandbox Code Playgroud)
将来当浏览器支持时Array.fromAsync(),这可以缩短为:
export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
return concatArrayBuffers(await Array.fromAsync(stream));
}
Run Code Online (Sandbox Code Playgroud)
stringnew Response(stream).text()就像上面描述的数组缓冲区一样,可以使用以下方法将流Uint8Array转换为字符串Response.text():
export async function streamToString(stream: ReadableStream<Uint8Array>): Promise<string> {
return await new Response(stream).text();
}
Run Code Online (Sandbox Code Playgroud)
TextDecoderStreamTextDecoderStream会将块流转换UInt8Array为块流string。这样您就可以直接将流的内容收集为字符串。请注意,Firefox 中的浏览器支持是在 2022 年 9 月才添加的,因此您可能还不想在生产中使用它。
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
let result = '';
const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
result += value;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
在支持它的浏览器中,您还可以使用异步迭代器协议使用此字符串流:
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
let result = '';
for (const chunk of stream.pipeThrough(new TextDecoderStream()).getReader())
result += chunk;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
或者在支持 的浏览器中Array.fromAsync(),甚至更短:
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
const chunks = await Array.fromAsync(stream.pipeThrough(new TextDecoderStream()).getReader()));
return chunks.join("");
}
Run Code Online (Sandbox Code Playgroud)
TextDecoder要将上述某些函数生成的 s 转换Uint8Array为字符串,您可以使用TextDecoder:
const buffer = await streamToArrayBuffer(res.body);
const text = new TextDecoder().decode(buffer);
Run Code Online (Sandbox Code Playgroud)
请注意,这只能用于整个内容,而不是单个UInt8Array块,因为某些字符可能由多个字节组成,并且可能在块之间分割。
new Response(stream).json()Uint8Array就像上面描述的数组缓冲区和字符串一样,可以使用以下方法将流解析为 JSON Response.json():
export async function streamToJson(stream: ReadableStream<Uint8Array>): Promise<unknown> {
return await new Response(stream).json();
}
Run Code Online (Sandbox Code Playgroud)
JSON.parse()使用上述任何方法将流转换为字符串,然后用于JSON.parse()解析该字符串。
joe*_*joe 29
对于那些有 aReadableStream并且想要从中获取文本的人,一个简短的技巧是将其包装在 new Response(或Request) 中,然后使用以下text方法:
let text = await new Response(yourReadableStream).text();
Run Code Online (Sandbox Code Playgroud)
pin*_*yid 23
res.json()返回一个承诺.试试......
res.json().then(body => console.log(body));
Run Code Online (Sandbox Code Playgroud)
Dan*_*ist 11
派对有点晚了,但是从使用Sharepoint Framework的Odata $批量请求生成的ReadableStream中获得一些有用的东西有一些问题.
和OP有类似的问题,但我的解决方案是使用与.json()不同的转换方法.在我的情况下.text()就像一个魅力.然而,为了从文本文件中获取一些有用的JSON,必须进行一些调整.
Chr*_*row 10
请注意,您只能读取一次流,因此在某些情况下,您可能需要克隆响应以重复读取它:
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))
Run Code Online (Sandbox Code Playgroud)
如果您只想将响应作为文本而不希望将其转换为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));
});
Run Code Online (Sandbox Code Playgroud)
要么
fetch('city-market.md')
.then(function(response) {
return response.text();
})
.then(function(myText) {
console.log(myText);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
79238 次 |
| 最近记录: |