【问题标题】:Retrieve data from a ReadableStream object?从 ReadableStream 对象中检索数据?
【发布时间】:2017-03-16 01:43:06
【问题描述】:

我如何从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();
    })

【问题讨论】:

  • @FrancescoPezzella 感谢您的回复。我试过 response.Body.json() ,但我得到 italic TypeError: Cannot read property 'json' of undefined italic 。这是因为 bodyUsed 属性也设置为 false 吗?但是,我可以在浏览器开发人员工具的响应选项卡下查看此正文。我想检索一条错误消息。
  • 所以您的问题完全与错误 400 条件有关?如果将处理程序更改为console.log(res.json()); 会发生什么?您看到预期的数据了吗?
  • @noob 如果res.status == 200,您是否尝试将响应作为流读取?
  • 只是我还是那个文档是plain错误的?不过,我确实用这个答案的解决方案修复了它。
  • 我知道已经有一段时间了,但为了让 stackoverflow 保持良好状态,请接受正确的答案。拥有超过 200 个赞的那个。

标签: javascript node.js reactjs fetch


【解决方案1】:

要从 ReadableStream 访问数据,您需要调用其中一种转换方法(可获取文档 here)。

举个例子:

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
  });

希望这有助于解决问题。

【讨论】:

  • 感谢您的回复。我已经尝试过了,但在 res.body 未定义时仍然遇到相同的错误。但是,我可以在第一个 then() 函数中使用 res.status 检索状态。似乎只有主体是 ReadableStream 对象。它似乎确实有一个属性被锁定,设置为 true?
  • 我尝试从第一个 .then() 函数返回的 json 响应中访问 res.body。为了更清楚,我在原始问题中添加了一个示例。谢谢!
  • 太棒了,使用 react 和 request native,想知道用 ReadableStream 做什么,这成功了。 ++
  • 只是一个提示,看起来很简单,但请确保您访问的后端实际上提供了有效的 JSON!绝对不是经验之谈。
【解决方案2】:

有些人可能会发现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 开始)。

【讨论】:

  • 有时对你来说真正的答案真的是#2哈哈,他们为什么要让 .json() 异步是有道理的,但它并不是立即显而易见的
【解决方案3】:

res.json() 返回一个承诺。试试...

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

【讨论】:

  • 我试过这个,它打印出 Promise 而不是正文。
  • 尝试链接.then调用:fetch(...).then(res => res.json()).then(data => console.log(data))
【解决方案4】:

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

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

【讨论】:

  • 谢谢!这对我有用。我使用简单的return $data; 从我的 Laravel 服务器发送 Illuminate http 响应。我终于能够在浏览器中使用fetch(...).then(response => response.text()).then(data => console.log(data)); 阅读此响应
【解决方案5】:

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

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))

【讨论】:

    【解决方案6】:

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

    【讨论】:

    • 欢迎 CityMarket.md
    【解决方案7】:

    我不喜欢当时的链接。第二个则无法访问状态。如前所述,“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
            }
        })
    })
    

    【讨论】:

    • 链接then 可帮助您检索最终解析的值(body)。嵌套它们会阻止您在没有回调或某种机制的情况下获得 body 值。想象一下:let body = await fetch(...).then(res => res.json()).then(data => data)。这不会以嵌套方式工作。要检查response.status,您始终可以在第一个then 中出现throw 异常,并将catch 添加到整个promise 链中。
    • 同意。在企业环境中首选。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-06-17
    • 1970-01-01
    • 2016-09-28
    • 2018-08-06
    相关资源
    最近更新 更多