18

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

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

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

我怎样才能从中获得上传进度?

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

例如。像这样的东西

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

谢谢。

4

2 回答 2

9

更新

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
}).then(r => r.json()).then(console.log)

正如凯尔所说,尚不支持 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 中删除了它,因为它有自己的实现/建议。

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

于 2018-10-17T17:33:38.643 回答
2

简短的回答:现在无法完成。

在此处查看规范:https ://fetch.spec.whatwg.org/#fetch-api

第二句表示使用 fetch 时无法跟踪请求进度。

fetch() 方法是用于获取资源的相对低级 API。它比 XMLHttpRequest 覆盖的范围略多,尽管目前在请求进展(而不是响应进展)方面缺乏它。

于 2018-10-16T15:20:58.697 回答