在循环中使用xhr对象进行html5 chunked上传

时间:2012-09-02 11:45:43

标签: javascript ajax html5 xmlhttprequest

专家,我面临的问题是循环浏览我为可恢复的分块上传创建的BLOB块。我遵循的方法如下: 我使用Blob.slice()来上传要上传的文件,推送队列中的所有块并尝试将它们发送到我的服务器。

我面临的问题是关于循环这些块。第一个块被成功发送,我最终从委托给xhr.onreadystatechange的函数中提到了下面提到的uploadNext方法。直到现在都很好,但这段代码在发送前两个块之后就停止了,并且没有循环。

以下代码是我迄今为止所取得的成就:

uploadFile: function(item, location, start, isresume) {
        var blob = item.file;

        const BYTES_PER_CHUNK = 1024 * 200 * 10; 
        const SIZE = blob.size;

        var chunkId = 0;
        var end = BYTES_PER_CHUNK;

        while(start < SIZE) {
            var chunkObj = {};
            // Note: blob.slice has changed semantics and been prefixed. See http://goo.gl/U9mE5.
            end = start + BYTES_PER_CHUNK;
            if(end > SIZE){
                end = SIZE;
            }
            if ('mozSlice' in blob) {
                chunkObj["chunk"] = blob.mozSlice(start, end);
                chunkObj["id"] = chunkId;
            } else {
                // var chunk = blob.webkitSlice(start, end);
                chunkObj["chunk"] = blob.slice(start, end);
                chunkObj["start"] = start;
                chunkObj["end"] = end-1;
                chunkObj["id"] = chunkId;
            }
            chunkId++;
            item.chunks.push(chunkObj);

            start = end ;
        }
        this.upload(item, location, SIZE, isresume);
    },

    upload: function(item, location, SIZE, isresume) {
        var xhr = new XMLHttpRequest();
        // Upload the first chunk
        xhr.upload.addEventListener("error", this.onFileUploadError.createDelegate(this, [item, xhr], 0), false);
        xhr.onload = this.getStatus.createDelegate(this, [item, xhr, isresume], 0);
        xhr.onreadystatechange = this.isChunkUploaded.createDelegate(this, [item, item.chunks[0], xhr, 0, SIZE, location, isresume], 0);
        xhr.open("PUT", location, true);
        xhr.setRequestHeader("Content-Range", "bytes " + item.chunks[0].start + "-" + item.chunks[0].end + "/" + SIZE);
        xhr.send(item.chunks[0].chunk);
    },

    uploadNext: function(item, xhr, index, SIZE, location, isresume) {
        if(index > item.chunks.length) {
            return;
        }

        console.log("uploading next chunk");

        xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("error", this.onFileUploadError.createDelegate(this, [item, xhr], 0), false);
        xhr.onload = this.getStatus.createDelegate(this, [item, xhr, isresume], 0);
        xhr.onreadystatechange = this.isChunkUploaded.createDelegate(this, [item, xhr], 0);
        xhr.open("PUT", location, true);
        xhr.setRequestHeader("Content-Range", "bytes " + item.chunks[index].start + "-" + item.chunks[index].end + "/" + SIZE);
        xhr.send(item.chunks[index].chunk);
        //this.uploadNext(item, xhr, index + 1, SIZE, location, isresume);
    },

    isChunkUploaded: function(item, chunkObj, request, index, SIZE, location, isresume, e) {
        if (request.readyState === 4) {
            console.log("chunk " + index + " uploaded");
            this.uploadNext(item, request, index + 1, SIZE, location, isresume);
        }
    },

P.S。我不能使用jquery(不要问为什么)。

1 个答案:

答案 0 :(得分:1)

没关系,这是正常的。我通过发送少于函数参数的函数参数而在我的结尾处犯了一个错误。