Подтвердить что ты не робот

Почему XMLHttpRequest ProgressEvent.lengthComputable будет ложным?

Я пытаюсь реализовать индикатор выполнения загрузки HTML5, используя поддержку XMLHttpRequest уровня 2 для событий прогресса.

В каждом примере, который вы видите, метод заключается в том, чтобы добавить прослушиватель событий к событию прогресса следующим образом:

req.addEventListener("progress", function(event) {
    if (event.lengthComputable) {
        var percentComplete = Math.round(event.loaded * 100 / event.total);
        console.log(percentComplete);
    }
}, false);

Такие примеры всегда, кажется, предполагают, что event.lengthComputable будет правдой. В конце концов, браузер знает длину отправляемого запроса, конечно?

Независимо от того, что я делаю, event.lengthComputable является ложным. Я тестировал это в Safari 5.1.7 и Firefox 12, как на OSX.

Мой сайт построен с использованием Django, и я получаю ту же проблему на своих dev и производственных настройках.

Полный код, который я использую для создания загрузки формы, показан ниже (с использованием jQuery):

form.submit(function() {
    // Compile the data.
    var data = form.serializeArray();
    data.splice(0, 0, {
        name: "file",
        value: form.find("#id_file").get(0).files[0]
    });
    // Create the form data.
    var fd = new FormData();
    $.each(data, function(_, item) {
        fd.append(item.name, item.value);
    });
    // Submit the data.
    var req = new XMLHttpRequest();
    req.addEventListener("progress", function(event) {
        if (event.lengthComputable) {
            var percentComplete = Math.round(event.loaded * 100 / event.total);
            console.log(percentComplete);
        }
    }, false);
    req.addEventListener("load", function(event) {
        if (req.status == 200) {
            var data = $.parseJSON(event.target.responseText);
            if (data.success) {
                console.log("It worked!")
            } else {
                console.log("It failed!")
            }
        } else {
            console.log("It went really wrong!")
        }
    }, false);
    req.addEventListener("error", function() {
        console.log("It went really really wrong!")
    }, false);
    req.open("POST", "/my-bar/media/add/");
    req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    req.send(fd);
    // Don't really submit!
    return false;
});

Я часами трахал свои волосы. Любая помощь ценится!

4b9b3361

Ответ 1

Привет, я нашел ответ от @ComFreek:

Я сделал ту же ошибку.

Я написал:

xhr.onprogress = uploadProgress;

Правильный должен быть

xhr.upload.onprogress = uploadProgress;

Ответ 3

У меня также возникла проблема с отправкой нескольких больших файлов с помощью AJAX (xmlhttprequest).

Обнаружено решение, и здесь используется целый script. Все, что вам нужно, это разместить следующую строку на странице HTML:

<input type="file" multiple name="file" id="upload_file" onchange="handleFiles(this)">

и используйте следующий script:

<script type="text/javacript">
    var filesArray;
    function sendFile(file)
    {
        var uri = "<URL TO PHP FILE>";
        var xhr = new XMLHttpRequest();
        var fd = new FormData();

        var self = this;

        xhr.upload.onprogress = updateProgress;
        xhr.addEventListener("load", transferComplete, false);
        xhr.addEventListener("error", transferFailed, false);
        xhr.addEventListener("abort", transferCanceled, false);
        xhr.open("POST", uri, true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(xhr.responseText); // handle response.
            }
        };
        fd.append('myFile', file);
        // Initiate a multipart/form-data upload
        xhr.send(fd);
    }
    function updateProgress (oEvent)
    {
        if (oEvent.lengthComputable)
        {
            var percentComplete = oEvent.loaded / oEvent.total;
            console.log(Math.round(percentComplete*100) + "%");
        } else {
            // Unable to compute progress information since the total size is unknown
            console.log("Total size is unknown...");
        }
    }

    function transferComplete(evt)
    {
        alert("The transfer is complete.");
    }

    function transferFailed(evt)
    {
        alert("An error occurred while transferring the file.");
    }

    function transferCanceled(evt)
    {
        alert("The transfer has been canceled by the user.");
    }
    function handleFiles(element)
    {
        filesArray = element.files;
        if (filesArray.length > 0)
        {
            for (var i=0; i<filesArray.length; i++)
            {
                sendFile(filesArray[i]);
            }
            filesArray = '';
        }
    }
    </script>

Ваш результат будет в консоли