Olası bir geçici çözüm, yapıcıyı kullanmak ve new Request()
ardından Request.bodyUsed
Boolean
özniteliği kontrol etmektir.
bodyUsed
Özniteliğin alıcı true döndürmesi gerekir disturbed
aksi takdirde ve yanlış.
akışın olup olmadığını belirlemek için distributed
Body
Karışımı uygulayan bir nesnenin disturbed
eğer
body
boş olmadığı ve onun stream
olduğu söylenir disturbed
.
Dönüş fetch()
Promise
içinden .then()
özyinelemeli zincirlenmiş .read()
bir çağrısına ReadableStream
zaman Request.bodyUsed
eşittir true
.
Not, yaklaşım, baytlar Request.body
uç noktaya akıtılırken baytlarını okumaz . Ayrıca, herhangi bir yanıt tarayıcıya tam olarak döndürülmeden önce yükleme tamamlanabilir.
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);
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));
}