Ajax Uploader大文件的高内存消耗

时间:2015-07-10 11:44:11

标签: javascript ajax filereader uploader

我正在尝试使用FileReader API将文件上传到服务器。

文件上传效果很好。虽然我是以块的形式上传文件,但是在上传后没有释放FormData对象使用的内存,即上传大文件会导致浏览器崩溃。

这是我的代码: 我想知道我做错了什么?

      function uid() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
              .toString(16)
              .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
          s4() + '-' + s4() + s4() + s4();
    }

    function parseFile(file) {

        var fileSize = file.size;

        var chunkSize = 10 * 1024 * 1024; // bytes
        var offset = 0;

        var block = null;
        var doUpload = null;
        var sendEndSignal = null;
        var id = uid();
        var chunks = {};
        var r = new FileReader();
        var xhr = new XMLHttpRequest();
        var fd = new FormData();

        var foo = function (evt) {

        }

        block = function (_offset, length, _file) {

            var blob = _file.slice(_offset, length + _offset);

            r.onload = foo;
            r.onloadend = (
                function (file, id, off) {

                    return function (evt) {
                        if (evt.target.error == null) {


                            off += chunkSize;
                            if (off >= fileSize) {
                                console.log("Done reading file");
                                return;
                            }
                            var fnc = block;
                            doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off);

                        } else {
                            alert("Read error: " + evt.target.error);
                            return;
                        }

                    }
                })(_file, id, _offset);

            r.readAsDataURL(blob);

        }

        doUpload = function (file, data, id, chunk, chunks, chunkSize,nx,off) {

            xhr = new XMLHttpRequest();
            fd = new FormData();

            fd.append(file.name + "-----" + id + "-----" + String(chunk), data);

            xhr.open("post", "Handler1.ashx", true);
            xhr.send(fd);

            xhr.addEventListener('readystatechange',
            function (e) {
                if (this.readyState === 4) {
                    chunks[Math.floor(chunk)] = 1;

                    var cnt = 0;
                    var cntDone = 0;
                    for (var key in chunks) {
                        if (chunks.hasOwnProperty(key)) {
                            cnt++;
                            if (chunks[key] === 1)
                                cntDone += 1;
                        }
                    }
                    if (nx)
                        nx(off,chunkSize,file);
                    if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
                        sendEndSignal(file, id, cnt - 1);
                }
            });

        }


        sendEndSignal = function (file, id, num) {

            fd = new FormData();
            xhr = new XMLHttpRequest();
            fd.append("Done-----" + file.name + "-----" + id, num);
            xhr.open("post", "Handler1.ashx", true);
            xhr.send(fd);
        }


        block(offset, chunkSize, file);

    }

谢谢。

更新 我使用jquery post而不是XMLHttpRequest和FormData解决了我的问题。 这就是我所做的:

<script type="text/javascript">

    function uid() {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
              .toString(16)
              .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
          s4() + '-' + s4() + s4() + s4();
    }

    function parseFile(file,index) {

        var fileSize = file.size;

        var chunkSize = 10 * 1024 * 1024; // bytes
        var offset = 0;

        var block = null;
        var doUpload = null;
        var sendEndSignal = null;
        var id = uid();
        var chunks = {};
        var r = new FileReader();


        var foo = function (evt) {

        }

        block = function (_offset, length, _file) {

            var blob = _file.slice(_offset, length + _offset);

            var div = document.getElementById("file-" + String(index));
            div.innerHTML = div.innerHTML + "*";

            r.onload = foo;
            r.onloadend = (
                function (file, id, off) {

                    return function (evt) {
                        if (evt.target.error == null) {



                            doUpload(file, evt.target.result, id, Math.floor(off / chunkSize), chunks, chunkSize, block, off,index);


                        } else {
                            alert("Read error: " + evt.target.error);
                            return;
                        }

                    }
                })(_file, id, _offset);

            r.readAsDataURL(blob);

        }

        doUpload = function (file, data, id, chunk, chunks, chunkSize, nx, off,ind) {

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "WebForm1.aspx/ProcessData",
                data: "{'data':'" + data + "','name':'" + file.name + "-----" + id + "-----" + String(chunk) + "'}",
                success: function (dd) {
                    debugger;

                    chunks[Math.floor(chunk)] = 1;

                    var cnt = 0;
                    var cntDone = 0;
                    for (var key in chunks) {
                        if (chunks.hasOwnProperty(key)) {
                            cnt++;
                            if (chunks[key] === 1)
                                cntDone += 1;
                        }
                    }

                    if (cnt === Math.ceil(file.size / chunkSize) && cnt === cntDone)
                        sendEndSignal(file, id, cnt - 1,ind);

                    if (nx) {
                        debugger;
                        off += chunkSize;
                        if (off >= file.size) {

                            return;
                        }
                        nx(off, chunkSize, file);
                    }

                },
                error: function (result) {

                    alert(JSON.stringify(result));
                }
            });
        }


        sendEndSignal = function (file, id, num,ind) {

            $.ajax({
                type: "POST",
                contentType: "application/json; charset=utf-8",
                url: "WebForm1.aspx/ProcessData",
                data: "{'data':'" + num + "','name':'" + "Done-----" + file.name + "-----" + id + "'}",
                success: function (dd) {
                    var div = document.getElementById("file-" + String(ind));
                    div.innerHTML = "<b>" + file.name + "</b> => DONE!!!!";
                },
                error: function (result) {

                    alert(JSON.stringify(result));
                }
            });

        }


        block(offset, chunkSize, file);

    }



    function xx(inp) {

        var i = 0;
        var file;
        var node = document.getElementById("dupl");
        debugger;
        while (node.hasChildNodes())
            node.removeChild(node.lastChild);


        for (i = 0; i < inp.files.length; i++) {

            file = inp.files[i];
            var dd = document.createElement("div");
            dd.id = "file-" + String(i);
            dd.innerHTML = "<b>" + file.name + "</b>";
            document.getElementById("dupl").appendChild(dd);
        }

        for (i = 0; i < inp.files.length; i++) {
            file = inp.files[i];
            parseFile(file,i);   
        }

    }

</script>

希望这对某人有用。

0 个答案:

没有答案