【发布时间】:2018-09-25 23:02:03
【问题描述】:
我正在尝试将一个大文件发送到服务器,因此我使用了分块技术以便以稳健的方式执行此操作。
private readonly sendChunk = (file: File, progressModel: ProgressResponseModel): void => {
const offset = progressModel.Offset;
if (offset > file.size)
throw new Error("Offset cannot be greater than the file size");
const expectedSize = progressModel.ExpectedChunkSize;
const blobChunk = file.slice(offset, expectedSize);
const xhr = new XMLHttpRequest();
xhr.onload = (ev: Event): void => {
if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
const progress = this.progressFromText(xhr.responseText);
if (progress.Offset >= 0) {
this.sendChunk(file, progress);
}
console.log(`${progress.Progress} %`);
}
}
xhr.open("POST", this._uploadChunkUrl, true);
xhr.send(blobChunk);
}
服务器发回从哪里开始新块以及它应该有多大。如您所见,上述函数以递归方式执行。
但是,如果文件需要发送超过 1 个块,我第二次调用 const blobChunk = file.slice(offset, expectedSize); 时会得到一个空块(长度为 0)。
我可以保证file arg 始终有效(当console.loged 时)。
我见过this question,但我确信我的文件没有被删除或重命名。 我也见过this issue。 Chrome 和 Firefox(最新版本)以及 Edge 的行为相同。
谢谢!
更新 好的,所以我做了一个虚拟方法来隔离这个问题:
readonly chunkIt = (file: Blob): void => {
var offset = 0;
var length = 512 * 1024;
while (offset >= 0) {
const blobChunk = file.slice(offset, length);
console.log(blobChunk);
offset += length;
if (offset > file.size) offset = -1;
}
}
并使用它:
$("input[name='fileUpload']").on("change", (e) => {
const files = e.target.files;
if (typeof files === "undefined" || files === null || files.length === 0)
e.preventDefault();
const file = files[0];
this._client.chunkIt(file);
});
仅第一次记录正确的Blob,以下均为空。
已解决
从这个问题 - Splitting a File into Chunks with Javascript 原来我忘了抵消我的end 索引。
【问题讨论】:
-
使用
file.splice -
我用的是typescript,
Blob接口里没有这个定义,只有slice()