javascript - 如何使用 fetch() 和 WhatWG 流获取文件上传进度

标签 javascript fetch-api whatwg-streams-api

注意:我不是在寻找任何替代品。我知道这可以通过 XMLHttpRequest 来完成。我也不关心浏览器支持。我只想了解新的/即将推出的标准。

我有一个 File对象,我可以像这样使用 PUT 上传它:

fetch(url, {
    method: "PUT",
    body: fileObject,
});

如何从中获取上传进度?

据我了解,获取选项的 body 可以是 ReadableStream .那么也许有一种方法可以将 File 对象包装到 ReadableStream 并从中获取进度状态?

例如。像这样

fetch(url, {
    method: "PUT",
    body: asReadableStream(fileObject, onProgress),
});

谢谢。

最佳答案

更新

Chrome 开始支持流式上传 https://chromestatus.com/features/5274139738767360

这是一个使用拉流的演示,请求在准备好接受更多数据进行上传时调用该拉流

let uploaded = 0
let buf = new Uint8Array(1024 * 50)
let start = Date.now()

var rs = new ReadableStream({
  pull(ctrl) {
    uploaded += buf.byteLength
    console.log('uploaded', uploaded)
    crypto.getRandomValues(buf)
    ctrl.enqueue(buf)
    if ((start + 1000) < Date.now()) ctrl.close()
  }
})

fetch('https://httpbin.org/post', {
  method: 'POST',
  body: rs,
  duplex: 'half'
}).then(r => r.json()).then(console.log)

正如Kyle所说,目前还不支持ReadableStream上传。 https://github.com/whatwg/fetch/issues/95

即使有可能,我也不会尝试通过流监控上传进度,(也就是说,如果 FetchObserver 成为现实)现在没有人在做这件事。但是 Mozilla 提出了一个看起来像这样的提议。

/*
enum FetchState {
  // Pending states
  "requesting", "responding",

  // Final states
  "aborted", "errored", "complete"
};
*/

fetch(url, {
  observe(observer) { 
    observer.onresponseprogress = e => console.log(e);
    observer.onrequestprogress = e => console.log(e);
    observer.onstatechange = n => console.log(observer.state)
  }
)

我记得很久以前我用一些实验性的标志测试过它,但再也找不到演示了,我猜他们把它从 MDN 中删除了,因为它有自己的实现/建议。

将字节排队到可读流或标识流并不意味着您已将数据上传到服务器,它仅表示请求要求更多数据以可能填满存储桶

关于javascript - 如何使用 fetch() 和 WhatWG 流获取文件上传进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52422662/

相关文章:

javascript - 发布到 localhost 时 fetch 返回 400

javascript - fetch api 从服务器获取错误消息而不是通用消息

javascript - Chrome : to play a video that is being downloaded via fetch/XHR

Javascript:如何访问名称为动态的属性?

javascript - 回车数控G代码

javascript - 获取 API 产生 "TypeError: failed to fetch"

javascript - 如何在不锁定主体流的情况下知道提取何时结束?

javascript - 为什么关键帧在 Firefox 上有效,但在 Chrome 上无效?

javascript - 如何限制用户在文本框中输入数字和特殊字符?