Eine mögliche Problemumgehung wäre, den new Request()
Konstruktor zu verwenden und dann das Request.bodyUsed
Boolean
Attribut zu überprüfen
Der bodyUsed
Getter des Attributs muss true if disturbed
und andernfalls false zurückgeben.
um festzustellen, ob Stream ist distributed
Ein Objekt, das das Body
Mixin implementiert, heißt disturbed
if , wenn
body
es nicht null ist und es stream
ist disturbed
.
Geben Sie den fetch()
Promise
von innen .then()
verketteten bis rekursiven .read()
Aufruf eines ReadableStream
Wann Request.bodyUsed
gleich gleich zurück true
.
Beachten Sie, dass der Ansatz die Bytes von nicht liest, Request.body
wenn die Bytes zum Endpunkt gestreamt werden. Außerdem kann der Upload abgeschlossen sein, bevor eine Antwort vollständig an den Browser zurückgegeben wird.
const [input, progress, label] = [
document.querySelector("input")
, document.querySelector("progress")
, document.querySelector("label")
];
const url = "/path/to/server/";
input.onmousedown = () => {
label.innerHTML = "";
progress.value = "0"
};
input.onchange = (event) => {
const file = event.target.files[0];
const filename = file.name;
progress.max = file.size;
const request = new Request(url, {
method: "POST",
body: file,
cache: "no-store"
});
const upload = settings => fetch(settings);
const uploadProgress = new ReadableStream({
start(controller) {
console.log("starting upload, request.bodyUsed:", request.bodyUsed);
controller.enqueue(request.bodyUsed);
},
pull(controller) {
if (request.bodyUsed) {
controller.close();
}
controller.enqueue(request.bodyUsed);
console.log("pull, request.bodyUsed:", request.bodyUsed);
},
cancel(reason) {
console.log(reason);
}
});
const [fileUpload, reader] = [
upload(request)
.catch(e => {
reader.cancel();
throw e
})
, uploadProgress.getReader()
];
const processUploadRequest = ({value, done}) => {
if (value || done) {
console.log("upload complete, request.bodyUsed:", request.bodyUsed);
// set `progress.value` to `progress.max` here
// if not awaiting server response
// progress.value = progress.max;
return reader.closed.then(() => fileUpload);
}
console.log("upload progress:", value);
progress.value = +progress.value + 1;
return reader.read().then(result => processUploadRequest(result));
};
reader.read().then(({value, done}) => processUploadRequest({value,done}))
.then(response => response.text())
.then(text => {
console.log("response:", text);
progress.value = progress.max;
input.value = "";
})
.catch(err => console.log("upload error:", err));
}