Скажите AJAX, что запрос был выполнен без отмены загрузки файла

Извините, если название вводило в заблуждение, нет простого способа сократить мою проблему в названии. В настоящее время я экспериментирую с загрузкой файлов AJAX; Раньше я выполнял стандартную загрузку файлов, но теперь я пытаюсь сделать интерфейс моего приложения немного лучше, добавив индикатор выполнения, который отслеживает ход загрузки файла и уведомляет пользователя, когда видео завершает загрузку, заканчивает обработку и помещается в базу данных.

Он работает в основном нормально, за исключением того факта, что Ajax в настоящее время работает над завершением выполнения моего скрипта. По сути, происходит то, что большинство вызовов выполняется из одного файла с именем uploadfiles.php, Я использую цикл с feof и запись прогресса в файл, который затем должен быть извлечен другим AJAX, который зацикливается, пока файл не сообщит ему, что запрос изменился / завершен.

Но, опять же, индикатор выполнения не перемещается, так как по какой-то причине первый AJAX-запрос ожидает uploadfiles.php полностью завершает выполнение (Что произойдет, когда файл завершит загрузку, обработку и будет перемещен, что сделает индикатор выполнения бессмысленным), и из-за этого не пускает следующий AJAX-запрос, который извлекает содержимое файла журнала. Я пробовал следующее:

  • Сделал ob_start(); and ob_end_flush() сразу после того, как файл перемещен из PHP-папки tmp в мою пользовательскую tmp-папку
  • Сделал flush()Я полагаю, что это то же самое, что и пункт выше.
  • Повторил что-то случайное и снова вспыхнул, надеясь, что что-то случится

Я также добавил ignore_user_abort() чтобы гарантировать, что запрос не будет прерван, если пользователь покидает страницу / запрос заканчивается или прерывается.

** Вот код JS:

    function uploadFiles()
{
var data2 = new FormData($("#specialform")[0]);

timestamp = new Date().getUTCMilliseconds();
timestamp = timestamp.toString();

data2.append('outputId', timestamp);

console.log(data2);

$.ajax({
type        : "POST",
url         : "actions/uploadfiles.php",
data        : data2,
processData : false,
contentType : false,
success: function(data)
{
alert('Finished first request');
getLog();
},
error: function (xhr, ajaxOptions, thrownError)
{
alert(xhr.responseText);
alert(thrownError);
},
xhr: function ()
{
var xhr = new window.XMLHttpRequest();

xhr.addEventListener("progress", function (evt)
{
if (evt.lengthComputable)
{
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
var percentComplete = percentComplete * 100;

$("#progressBar").css({ width : percentComplete + '%' });

if ( percentComplete >= 100 )
xhr.abort();
}
else
console.log('unable to complete');
}, false);

return xhr;
},
})
.fail(function(data)
{
console.log(data);
});

//return {'error' : 'No files', 'result' : null};
}

function getLog()
{
if ( finished == false )
{
console.log("logs/" + timestamp);

$.ajax({
type        : "GET",
url         : "logs/" + timestamp,
processData : false,
contentType : false,
success: function(data)
{
if ( data == "processing" && !processed )
{
alert('processing video');

$("#progressBar").css({ 'background-color' : 'yellow' });

processed = true;
}

if ( data == "done" )
{
alert('finished conversion');

$("#progressBar").css({ 'background-color' : 'green' });

finished = true;
}

if ( $.isNumeric(data) )
$("#progressBar").css({ width : data + '%' });

console.log(data);
}
});

setTimeout(getLog, 1000);
}
}

Вот код PHP:

<?php

require '../Init.php';

define('TMP_PATH', PATH.'/tmp');
define('V_STORE', PATH.'/resources/videos');
define('FFMPEG_PATH', 'F:/Webserver/ffmpeg/bin/ffmpeg.exe');

// ...

ob_start();

echo "END";

ob_end_flush();
flush();

// ...

$remote = fopen($_FILES['file']['tmp_name'], 'r');
$local = fopen($filename, 'w');

$read_bytes = 0;

set_time_limit(28800000);
ignore_user_abort(true);

$interval = 0;

while( !feof($remote) )
{
$buffer = fread($remote, 2048);
fwrite($local, $buffer);

$read_bytes += 2048;

$progress = min(100, 100 * $read_bytes / $filesize);

if ( $interval <= 0 )
{
file_put_contents('../logs/'.$logFile, $progress);

$interval = 1000;
}
else
$interval--;
}

// ...

$proc = popen(FFMPEG_PATH.' -i '.$filename.' -b '.$newBitrate.' '.V_STORE.'/'.$video_id.'.mp4', 'r');

while (!feof($proc))
{
file_put_contents('../logs/'.$logFile, fread($proc, 4096));
}

file_put_contents('../logs/'.$logFile, "done");

sleep(5);

unlink('../logs/'.$logFile);

Не беспокойся о Init.php как (В этом случае) он используется только для PATH постоянная

Заранее спасибо.

0

Решение

Используете ли вы сеансы на основе файлов PHP в файле Init.php (или в другом месте)? По умолчанию эти файлы блокируются до тех пор, пока сессия не будет эффективно закрыта, позволяя выполнять только один запрос за раз.

Если это так, вам нужно закрыть сеанс в файле загрузки с помощью:

session_write_close();
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]