[英]Retrieve data from a ReadableStream object?
如何從ReadableStream
對象獲取信息?
我正在使用 Fetch 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?
}
})
為了從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": "..." }
});
編輯:如果您的數據返回類型不是 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
});
希望這有助於澄清事情。
有些人可能會發現一個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 版開始)。
res.json()
返回一個承諾。 嘗試 ...
res.json().then(body => console.log(body));
聚會有點晚了,但在從使用 Sharepoint 框架的 Odata $batch 請求生成的ReadableStream
中獲取有用的東西時遇到了一些問題。
與 OP 有類似的問題,但我的解決方案是使用與.json()
不同的轉換方法。 在我的情況下.text()
就像一個魅力。 然而,為了從文本文件中獲取一些有用的 JSON,需要進行一些操作。
請注意,您只能讀取一次流,因此在某些情況下,您可能需要克隆響應以重復讀取它:
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))
如果您只想將響應作為文本而不想將其轉換為 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
}
})
})
對於那些擁有ReadableStream
並想從中獲取文本的人來說,一個簡短的技巧是將其包裝在一個新的Response
(或Request
)中,然后使用text
方法:
let text = await new Response(yourReadableStream).text();
我從MDN 上的這個頁面得到了解決方案。 這對我有幫助。 我認為這是因為 API 返回純文本。
您可能提出了錯誤的問題來解決您的問題,但這里是您實際問題的答案。 靈感可能來自 Node.js stream/consumers
模塊的源代碼。
res.body
是一個ReadableStream
,它以Uint8Array
的形式發出塊。 以下函數將收集單個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);
}
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;
}
在閱讀下一篇文章之前,我剛剛遇到同樣的問題超過 12 個小時,以防萬一這對任何人都有幫助。 在 _api 頁面中使用 nextjs 時,您將需要使用 JSON.stringify(whole-response) 然后使用 res.send(JSON.stringify(whole-response)) 將其發送回您的頁面,並且在客戶端收到它時您需要將其翻譯回 json 格式以便它可用。 這可以通過閱讀他們的序列化部分來弄清楚。 希望能幫助到你。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.