|

Laboratorio: descargas múltiples consecutivas mediante AJAX

Quizás el título parece un tanto extraño, pero quizás no es fácil resumirlo. Se trata de seleccionar varios archivos para bajar y que en vez de bajarlos todos a la vez, se vayan descargando de forma consecutiva, uno detrás de otro.

Para ello vamos a usar AJAX, para ir comprobando qué archivo es el que se está bajando. También usaremos un fichero que contendrá que archivos están en proceso de descargarse, siendo la primera fila del fichero el archivo actual. Cuando finalicen las descargas, se realizará una llamada para borrar el fichero auxiliar.

Cuando se termina de enviar un fichero, mediante el método que ya explicamos, se borrará del fichero auxiliar la primera fila (fichero acabado de enviar), por lo que el proceso AJAX encontrará que el fichero actual y el primero del fichero auxiliar son distintos, por lo que solicitará bajar el nuevo archivo.

Cuando un fichero se descarga, se deselecciona de la lista y se resalta para hacer ver al usuario el cambio de estado.

La parte web es la siguiente:

var fichActual = "";
var refresco = 100;
// Creación del objeto AJAX
function ajaxobj() {
try {
_ajaxobj = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
_ajaxobj = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
_ajaxobj = false;
}
}
if (!_ajaxobj && typeof XMLHttpRequest!='undefined') {
_ajaxobj = new XMLHttpRequest();
}
return _ajaxobj;
}
// Descarga de un fichero
function descarga(id) {
// Necesitamos un ID para referenciar las descargas
if (!id) {
id = Math.random();
}
var ficheros = "";
var lista = document.forms[0].ficheros;
// Obtenemos los ficheros seleccionados
fichActual = "";
var haymas = false;
for (var i=0; i<lista.length; i++) {
if (lista[i].checked) {
haymas = true;
if (fichActual == "") {
fichActual = lista[i].value;
}
ficheros += "&ficheros[]="+lista[i].value;
}
}
// Iniciamos la descarga, que obligatoriamente será un fichero adjunto
if (fichActual != "") {
document.location = "download.php?id="+id+ficheros;
// Iniciamos la comprobacion de que fichero se está descargando
compruebaFicheros(id);
}
// Borro el fichero
if (!haymas) {
ajax = ajaxobj();
ajax.open("GET", "download.php?delete=OK&id="+id, true);
ajax.send(null);
}
}
// Comprueba que fichero se está descargando,
// cuando sea distinto al actual, se inicia
// la descarga del nuevo fichero
function compruebaFicheros(id) {
ajax = ajaxobj();
ajax.open("GET", "download.php?check=OK&id="+id, true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
// Si es el mismo fichero se sigue comprobando
if (fichActual == "" || (ajax.responseText == "" || ajax.responseText == fichActual)) {
setTimeout("compruebaFicheros('"+id+"')", refresco);
// Si son distintos ficheros se empieza a descargar el nuevo fichero
} else {
// Primero se avisa de que el fichero se ha descargado
var lista = document.forms[0].ficheros;
for (var i=0; i<lista.length; i++) {
if (lista[i].value == fichActual) {
lista[i].checked = false;
lista[i].parentNode.className = "ok";
}
}
fichActual = "";
descarga(id);
}
}
}
ajax.send(null);
}

El script PHP es el siguiente:

$id = $_GET["id"];
$ficheros = $_GET["ficheros"];
// Orden de borrar el fichero auxiliar
if (isset($_GET["delete"])) {
unlink($id.'.csv');
// Qué fichero se está enviando
} else if (isset($_GET["check"])) {
// Miramos el primer fichero de la lista
// que está contenido en el fichero auxiliar
if (file_exists($id.'.csv')) {
$f = fopen($id.'.csv', "r");
$ficheros = fread($f, filesize($id.'.csv'));
fclose($f);
$ficheros = split("\n", $ficheros);
echo $ficheros[0];
} else {
echo "";
}
// Enviando el fichero
} else {
// Si no existe el fichero auxiliar lo creo
if (!file_exists($id.'.csv')) {
$f = fopen($id.'.csv', 'w');
for ($i=0; $i<sizeof($ficheros); $i++) {
fwrite($f, $ficheros[$i]."\n");
}
fclose($f);
}
// Devuelvo el fichero
if (sizeof($ficheros) > 0) {
header("Content-type: application/force-download");
header("Content-Transfer-Encoding: Binary");
header("Content-length: ".filesize($ficheros[0]));
header("Content-disposition: attachment; filename=\"".basename($ficheros[0])."\"");
readfile($ficheros[0]);
// Modificamos la lista de ficheros que nos falta
if (sizeof($ficheros) > 1) {
$f = fopen($id.'.csv', 'w');
for ($i=1; $i<sizeof($ficheros); $i++) {
fwrite($f, $ficheros[$i]."\n");
}
fclose($f);
} else {
$f = fopen($id.'.csv', 'w');
fclose($f);
}
}
}

Código

Similar Posts