XMLHttpRequest в Google-Chrome не сообщает о событиях прогресса

Привет всем, у меня есть этот код:

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    var data = generateRandomData(currentPayloadId);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
    }
    else {
        total = loaded = totalSize;
    }
}

Кроме того, мой сервер отвечает на первоначальный запрос OPTIONS для upload.aspx с 200 и Access-Control-Allow-Origin: *, а затем происходит второй запрос POST

Все кажется на месте, и он отлично работает в FireFox, но в G Chrome обработчик updateProgress вызывается не только один раз, а затем lengthComputable имеет значение false.

Мне нужен Access-Control-Allow-Origin: * потому что это междоменный вызов, родительский скрипт является ресурсом на другом сервере, чем домен upload.aspx

Кто-нибудь может дать мне подсказки, подсказки, помогите пожалуйста? это известная проблема с G Chrome?

Спасибо! Яйцеклетки

5 ответов

Я думаю, что у меня есть решение вашей проблемы
Я не знаю, что стоит за этой функцией "generateRandomData()"

var data = generateRandomData(currentPayloadId)

Это работает, когда я перехожу на это:

var data = new FormData();
data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);

Небольшое объяснение: вам нужно вручную добавить к форме данных файл ввода формы, где fileToUpload является <input type="file" name="fileToUpload" id="fileToUpload" />
И в твоем updateProgress функция в IF часть вы можете добавить что-то вроде этого, чтобы отслеживать прогресс console.log(evt.total +" - "+ evt.loaded)

Это работает в браузере Google Chrome. Я протестировал в новой версии браузера 57
Я сделал для себя форму загрузки 4 года назад, что означает, что этот код работает и в старой версии браузера.

Весь фрагмент кода будет выглядеть так

function test()
{
    req = new XMLHttpRequest();
    req.upload.addEventListener("progress", updateProgress, false);
    req.addEventListener("readystatechange", updateProgress, false);
    req.addEventListener("error", uploadFailed, false);
    req.addEventListener("abort", uploadCanceled, false);

    //var data = generateRandomData(currentPayloadId);
    var data = new FormData();
    data.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
    totalSize = data.length;

    req.open("POST", "www.mydomain.com/upload.aspx");
    start = (new Date()).getTime();
    req.send(data);
}

function updateProgress(evt)
{
    if (evt.lengthComputable) {
        total = totalSize = evt.total;
        loaded = evt.loaded;
        console.log(evt.total +" - "+ evt.loaded)
    }
    else {
        total = loaded = totalSize;
    }
}

У меня была эта проблема, когда страница, которую вы загружаете, не содержит

  Content-Length: 12345

в заголовке, где 12345 - длина ответа в байтах. Без параметра длины функция прогресса не будет работать.

Во-первых, убедитесь, что "www.example.com" добавляется в manifest.json, вот так:

manifest.json

 {
   ..
   "permissions": [
     "http://www.example.com/",
     "https://www.example.com/",
   ],
   ..
 }

Тогда я думаю, что ваш пример должен работать.

Более подробную информацию об использовании xhr в расширениях Google Chrome можно найти здесь.

Также стоит взглянуть на документы CSP, если то, что я указал выше, не подходит.

Я использую jQuery для такого прогресса:

    $.ajax({
        url : furl,
        type : method,
        data : data,
        //...
        },
        xhr : function () {
            //upload Progress
            var xhr = $.ajaxSettings.xhr();
            if (xhr.upload) {
                    xhr.upload.addEventListener('progress', function (event) {
                        var percent = 0;
                        var position = event.loaded || event.position;
                        var total = event.total;
                        if (event.lengthComputable) {
                            percent = Math.ceil(position / total * 100);
                        }
                        //update progressbar
                        $(".progress-bar").css("width",  + percent + "%");
                        $(" .status").text(position + " / " + total + " (" + percent + "%)");
                    }, true);
            }
            return xhr;
        },

Это может быть просто проблема совместимости со свойством XMLHttpRequest.upload. Он возвращает объект XMLHttpRequestUpload, но если вы попытаетесь найти эту спецификацию объекта в MDN, ее не будет, так как мы узнаем, какие браузеры полностью ее поддерживают.

XMLHttpRequest.upload Совместимость Совместимость для свойства XMLHttpRequest.upload

Вы пробовали слушать прогресс прямо на xhr:

req.addEventListener("progress", updateProgress, false);
Другие вопросы по тегам