13

進行状況イベントのXMLHttpRequestレベル2サポートを使用して、HTML5の方法でアップロード進行状況バーを実装しようとしています。

表示されるすべての例で、メソッドは次のように進行状況イベントにイベントリスナーを追加することです。

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

このような例では、event.lengthComputableがtrueになると常に想定しているようです。結局のところ、ブラウザは送信するリクエストの長さを知っていますよね?

私が何をしても、event.lengthComputableはfalseです。私はこれをSafari5.1.7とFirefox12の両方でOSXでテストしました。

私のサイトはDjangoを使用して構築されていますが、開発と本番のセットアップで同じ問題が発生します。

フォームのアップロードを生成するために使用している完全なコードを以下に示します(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;
});

私はこれで何時間も髪を引き裂いてきました。助けていただければ幸いです。

4

3 に答える 3

36

ねえ私は@ComFreekからの答えを見つけました:

私も同じ過ちを犯しました。

私が書いた行は次のとおりです。

xhr.onprogress = uploadProgress;

正しいものは

xhr.upload.onprogress = uploadProgress;
于 2012-07-05T12:03:57.793 に答える
1

これを見てください: https ://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

xhr.upload.addEventListener('progress'、function(e){})も機能します。

于 2013-07-08T10:25:21.433 に答える
1

また、AJAX(xmlhttprequest)を使用して複数の大きなファイルを送信する際に問題が発生しました。

解決策を見つけました。これが私が使用するスクリプト全体です。必要なのは、HTMLページに次の行を配置することだけです。

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

次のスクリプトを使用します。

<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>

結果はコンソールに表示されます

于 2014-06-09T14:24:45.760 に答える