从ReadableStream对象检索数据?


135

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

我正在使用Fetch API,但从文档中看不出来。

正文以a形式返回ReadableStream,我只想访问此流中的一个属性。在浏览器开发工具的Response下,我似乎以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();
    })


2
@FrancescoPezzella感谢您的回复。我已经尝试过response.Body.json(),但是我收到斜体字 TypeError:无法读取未定义斜体字的属性'json' 。这是因为bodyUsed属性也设置为false吗?但是,我可以在浏览器开发人员工具的“响应”选项卡下查看此正文。我想找一条错误消息。
2013年

因此,您的问题完全与错误400条件有关?如果将处理程序更改为,会发生什么console.log(res.json());?您看到期望的数据了吗?
Ashley'CptLemming'Wilson

@noob是否尝试将响应读取为流res.status == 200
guest271314

难道只是我或文档平原错了吗?我确实通过此答案的解决方案对其进行了修复。
卢西奥'18

Answers:


177

为了从中访问数据,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
  });

希望这有助于清理问题。


1
感谢您的回复。我已经尝试过了,在res.body未定义的地方仍然遇到相同的错误。我能够使用res.status首先在then()函数中检索状态。似乎只有正文是ReadableStream对象。它似乎具有锁定的属性,该属性设置为true吗?
noob

您想在哪里访问res.body(这不是我的示例的一部分)?您能否在原始问题中共享一些示例代码,以更清楚地了解问题所在。
Ashley'CptLemming'Wilson

1
我尝试从第一个.then()函数返回的json响应中访问res.body。我为最初的问题添加了一个样本,以更加清楚。谢谢!
noob

1
太棒了,使用本机进行响应和请求,并想知道世界上如何使用ReadableStream,这就是成功的秘诀。++
edencorbin

只是一个提示,似乎很简单,但是请确保您要访问的后端实际上提供了有效的JSON!绝对不是凭经验说话。
abelito

44

某些人可能会发现一个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功能,但是可以运行await在Chrome的控制台直接语句(如版本62)。


1
有时,您的真正答案确实是#2哈哈,这使他们为什么使.json()异步是有意义的,但并没有立即变得很明显
Sanchit Batra


12

聚会晚了一点,但是在ReadableStream使用Sharepoint框架从Odata $ batch请求的产品中获取有用的东西时遇到了一些问题。

遇到了与OP类似的问题,但是在我的案例中,解决方案是使用与相比不同的转换方法.json()。就我而言,它.text()就像一种魅力。但是,必须进行一些修改才能从文本文件中获取一些有用的JSON。


2
谢谢!这对我有用。我正在从Laravel服务器发送一个带有Illuminate http响应的简单邮件return $data;。我终于能够通过fetch(...).then(response => response.text()).then(data => console.log(data));
Cameron Hudson

10

如果您只是想将响应作为文本而不希望将其转换为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);
  });

2

我不喜欢那时的连锁店。然后,第二个将无法访问状态。如前所述,“ response.json()”返回一个承诺。在类似于第二秒的行为中返回“ response.json()”的当时结果。它具有响应范围内的额外好处。

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

链接then可帮助您检索最终的解析值(body)。嵌套它们会阻止您在body没有回调或某种某种机制的情况下获取值。想象一下:let body = await fetch(...).then(res => res.json()).then(data => data)。这不会以嵌套方式工作。要进行检查,response.status您始终可以throw在first中then添加一个异常,然后catch在整个promise链中添加一个。
奥卡·戈麦斯·阿尔卡尼兹(OscarGómezAlcañiz)

0

请注意,您只能读取一次流,因此在某些情况下,可能需要克隆响应才能重复读取它:

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))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.