filedownload - download file ajax php
Descargue el archivo CSV usando "AJAX" (6)
Bueno, el objetivo de usar AJAX es evitar una recarga visible de la página. Si desea una descarga, quiere lo contrario, una nueva solicitud del navegador. Yo diría que simplemente crea un botón simple que apunta a tu página php.
Estoy tratando de realizar una tarea bastante simple para mi sitio web, pero no estoy seguro de cómo hacerlo. Quiero que el usuario vea una tabla, luego haga clic en un botón, y en ese momento el usuario puede guardar el archivo. contenido de esa tabla como un archivo csv. Esta solicitud a veces puede ser bastante complicada, así que genero una página de progreso para alertar al usuario.
Tengo la mayoría de las cosas resueltas, excepto en realidad generar el archivo csv. (Yo uso jQuery y PHP)
el código jQuery se ejecuta al hacer clic:
hmis_query_csv_export: function(query_name) {
$.uiLock(''<p>Query Loading.</p><img src="/images/loading.gif" />'')
$.get({
url: ''/php_scripts/utils/csv_export.php'',
data: {query_name: query_name},
success: function(data) {
$.uiUnlock();
}
});}
el PHP relevante:
header("Content-type: text/x-csv");
header("Content-Disposition: attachment; filename=search_results.csv");
//
//Generate csv
//
echo $csvOutput
exit();
Lo que hace esto es enviar el texto como el archivo PHP, pero no genera una descarga. ¿Qué estoy haciendo mal?
La mejor manera de lograr esto es usar un URI de datos de la siguiente manera:
- Realice la llamada AJAX al servidor de la forma habitual
- Generar el CSV en el lado del servidor
- Devuelve los datos (ya sea al descubierto o dentro de una estructura JSON)
- Crear un URI de datos en Javascript utilizando los datos devueltos
- Establezca window.location.href en el URI de datos
Consulte este enlace para obtener instrucciones (párrafo 3, específicamente): http://en.wikipedia.org/wiki/Data_URI_scheme
De esta forma, no es necesario que guarde ningún archivo en el servidor, y tampoco necesita utilizar iframes o elementos de formulario ocultos ni ninguno de esos hacks.
No creo que puedas hacer la descarga del navegador usando una solicitud AJAX / JS. Intente usar un iframe oculto que navegue a la página que genera el CSV
Para hacer eco y expandir lo que otros han dicho, realmente no se puede enviar el archivo usando AJAX. Una de las razones para esto es (y alguien me corrige si me equivoco con esto, por favor) que la página en la que se encuentra actualmente ya ha enviado sus encabezados de contenido; no puede volver a enviarlos a la misma ventana, incluso con una solicitud AJAX (que es lo que intenta hacer su archivo PHP).
Lo que he hecho antes en proyectos es simplemente proporcionar un enlace (con target = "_ blank" o redirección javascript) a una página de descarga de PHP por separado. Si está utilizando Apache, consulte también mod_xsendfile.
Si está forzando una descarga, puede redirigir la página actual al enlace de descarga. Como el enlace generará un diálogo de descarga, la página actual (y su estado) se mantendrá en su lugar.
Enfoque básico:
$(''a#query_name'').click(function(){
$(''#wait-animation'').show();
document.location.href = ''/php_scripts/utils/csv_export.php?query_name=''+query_name;
$(''#wait-animation'').hide();
});
Más complicado:
$(''a#query_name'').click(function(){
MyTimestamp = new Date().getTime(); // Meant to be global var
$(''#wait-animation'').show();
$.get(''/php_scripts/utils/csv_export.php'',''timestamp=''+MyTimestamp+''&query_name=''query_name,function(){
document.location.href = ''/php_scripts/utils/csv_export.php?timestamp=''+MyTimestamp+''&query_name=''+query_name;
$(''#wait-animation'').hide();
});
});
En script PHP:
@header("Last-Modified: " . @gmdate("D, d M Y H:i:s",$_GET[''timestamp'']) . " GMT");
@header("Content-type: text/x-csv");
// If the file is NOT requested via AJAX, force-download
if(!isset($_SERVER[''HTTP_X_REQUESTED_WITH'']) || strtolower($_SERVER[''HTTP_X_REQUESTED_WITH'']) != ''xmlhttprequest'') {
header("Content-Disposition: attachment; filename=search_results.csv");
}
//
//Generate csv
//
echo $csvOutput
exit();
La URL de ambas solicitudes debe ser la misma para engañar al navegador y no para iniciar una nueva descarga en document.location.href
, sino para guardar la copia en la memoria caché. No estoy totalmente seguro, pero parece bastante prometedor.
EDITAR. Lo intenté con un archivo de 10 MB y parece que val () es demasiado lento para insertar los datos. Hurrumph.
Está bien, así que le di a este otro que se vaya. ¡Esto puede o no ser completamente loco! La idea es hacer una solicitud de AJAX para crear los datos, luego usar la devolución de llamada para insertar los datos en un formulario oculto en la página actual que tiene una acción de una tercera página de "descarga"; después de la inserción, el formulario se envía automáticamente, la página de descarga envía encabezados y se hace eco de la POST, y et voila, descarga.
Mientras tanto, en la página original tiene una indicación de que el archivo se está preparando, y cuando termina el indicador se actualiza.
NOTA: este código de prueba no se prueba exhaustivamente y no tiene comprobaciones reales de seguridad (o ninguna). Lo probé con un archivo CSV de 1.5MB que tenía sobre y era bastante ágil.
Index.html
<a id="downloadlink" href="#">Click Me</a>
<div id="wait"></div>
<form id="hiddenform" method="POST" action="download.php">
<input type="hidden" id="filedata" name="data" value="">
</form>
test.js
$(document).ready(function(){
$("#downloadlink").click(function(){ // click the link to download
lock(); // start indicator
$.get("create.php",function(filedata){ // AJAX call returns with CSV file data
$("#filedata").val(filedata); // insert into the hidden form
unlock(); // update indicator
$("#hiddenform").submit(); // submit the form data to the download page
});
});
function lock(){
$("#wait").text("Creating File...");
}
function unlock(){
$("#wait").text("Done");
}
});
create.php
<?php
//create $data
print $data;
?>
descargar.php
<?php
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: text/x-csv");
header("Content-Disposition: attachment;filename=/"search_results.csv/"");
if($_POST[''data'']){
print $_POST[''data''];
}
?>