Một giải pháp khả thi là sử dụng hàm new Request()tạo sau đó kiểm tra Request.bodyUsed Booleanthuộc tính
Các bodyUsedgetter của thuộc tính phải trả về true nếu disturbed, và sai khác.
để xác định xem luồng có distributed
Một đối tượng thực hiện Bodymixin được cho là disturbedif
bodykhông phải là null và nó streamlà disturbed.
Trả về fetch() Promisetừ bên trong .then()chuỗi để .read()gọi đệ quy của một ReadableStreamkhi Request.bodyUsedbằng true.
Lưu ý, phương pháp này không đọc các byte Request.bodykhi các byte được truyền trực tiếp đến điểm cuối. Ngoài ra, quá trình tải lên có thể hoàn thành tốt trước khi bất kỳ phản hồi nào được trả lại đầy đủ cho trình duyệt.
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));
}