Búsqueda de sitios web

Descargar archivo usando JavaScript/jQuery


Tengo un requisito muy similar especificado aquí.

Necesito que el navegador del usuario inicie una descarga manualmente cuando $ ('a#someID').click();

Pero no puedo usar el método window.href, ya que reemplaza el contenido de la página actual con el archivo que estás intentando descargar.

En cambio, quiero abrir la descarga en una nueva ventana/pestaña. ¿Cómo es esto posible?

Respuesta #1

Usa un <iframe> invisible:

<iframe id="my_iframe" style="display:none;"></iframe>
<script>
function Download(url) {
    document.getElementById('my_iframe').src = url;
};
</script>

Para forzar al navegador a descargar un archivo que de otro modo podría renderizar (como archivos HTML o de texto), necesitas que el servidor establezca el tipo MIME del archivo a un valor sin sentido, como application/x-please-download-me o alternativamente application/octet-stream, que se utiliza para datos binarios arbitrarios.

Si solo quieres abrirlo en una nueva pestaña, la única manera de hacer esto es que el usuario haga clic en un enlace con su atributo target establecido en _blank.

En jQuery:

$('a#someID').attr({target: '_blank', 
                    href  : 'http://localhost/directory/file.pdf'});

Cada vez que se haga clic en ese enlace, se descargará el archivo en una nueva pestaña/ventana.

Respuesta #2

Actualización de navegadores modernos 2019

Este es el enfoque que ahora recomendaría con algunas salvedades:

  • Se requiere un navegador relativamente moderno
  • Si se espera que el archivo sea muy grande, probablemente deberías hacer algo similar al enfoque original (iframe y cookie) porque algunas de las operaciones siguientes podrían consumir probablemente memoria del sistema al menos tan grande como el archivo que se está descargando y/o otros efectos interesantes en la CPU.

fetch('https://jsonplaceholder.typicode.com/todos/1')
   // check to make sure you didn't have an unexpected failure (may need to check other things here depending on use case / backend)
  .then(resp => resp.status === 200 ? resp.blob() : Promise.reject('something went wrong'))
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    // the filename you want
    a.download = 'todo-1.json';
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    // or you know, something with better UX...
    alert('your file has downloaded!'); 
  })
  .catch(() => alert('oh no!'));

Enfoque original de 2012 basado en jQuery/iframe/cookie

He creado el complemento jQuery File Download (Demo) (GitHub) que también podría ayudarte con tu situación. Funciona de manera bastante similar con un iframe, pero tiene algunas características interesantes que he encontrado bastante útiles:

  • Muy fácil de configurar con gráficos agradables (jQuery UI Dialog, pero no requerido), todo también está probado

  • El usuario nunca abandona la misma página desde la que inició la descarga de un archivo. Esta función se está volviendo crucial para las aplicaciones web modernas

  • Las funciones successCallback y failCallback te permiten ser explícito sobre lo que el usuario ve en cada situación

  • En conjunto con jQuery UI, un desarrollador puede mostrar fácilmente un modal indicando al usuario que se está realizando una descarga de archivo, cerrar el modal después de que la descarga comienza o incluso informar al usuario de manera amistosa que ha ocurrido un error. Vea la demostración para un ejemplo de esto.

Aquí hay una demostración de caso de uso simple utilizando el origen del complemento con promesas. La página de demostración incluye muchos otros ejemplos de 'mejor experiencia de usuario' también.

$.fileDownload('some/file.pdf')
    .done(function () { alert('File download a success!'); })
    .fail(function () { alert('File download failed!'); });

Respuesta #3

function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    // If you don't know the name or want to use
    // the webserver default set name = ''
    link.setAttribute('download', name);
    link.href = uri;
    document.body.appendChild(link);
    link.click();
    link.remove();
}

Comprueba si tu(s) navegador(es) objetivo ejecutarán el fragmento anterior sin problemas:
http://caniuse.com/#feat=download

Respuesta #4

Me sorprende que no mucha gente conozca el atributo download para los elementos a. ¡Por favor, ayuda a difundir la información sobre él! Puedes tener un enlace html oculto y simular un clic en él. Si el enlace html tiene el atributo download, descarga el archivo, no lo visualiza, sin importar qué. Aquí está el código. Descargará una imagen de un gato si puede encontrarla.

document.getElementById('download').click();
<a href="https://docs.google.com/uc?id=0B0jH18Lft7ypSmRjdWg1c082Y2M" download id="download" hidden></a>

Nota: Esto no es compatible con todos los navegadores: http://www.w3schools.com/tags/att_a_download.asp

Respuesta #5

Recomiendo usar el atributo download para descargar en lugar de jQuery:

<a href="your_link" download> file_name </a>

Esto descargará su archivo, sin abrirlo.

Respuesta #6

Esto podría ser útil si no necesitas navegar a otra página. Esta es una función básica de JavaScript, por lo que puede usarse en cualquier plataforma donde el backend esté en JavaScript

window.location.assign('any url or file path')

Respuesta #7

Si ya estás utilizando jQuery, podrías aprovecharlo para producir un fragmento más pequeño
Una versión en jQuery de la respuesta de Andrew:

var $idown;  // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
  if ($idown) {
    $idown.attr('src',url);
  } else {
    $idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
  }
},
//... How to use it:
downloadURL('http://whatever.com/file.pdf');

Respuesta #8

Funciona en Chrome, Firefox e IE8 en adelante.

var link=document.createElement('a');
document.body.appendChild(link);
link.href=url ;
link.click();

Respuesta #9

Terminé usando el siguiente fragmento y funciona en la mayoría de los navegadores, aunque no lo he probado en IE.

let data = JSON.stringify([{email: "[email ", name: "test"}, {email: "[email ", name: "anothertest"}]);

let type = "application/json", name = "testfile.json";
downloader(data, type, name)

function downloader(data, type, name) {
	let blob = new Blob([data], {type});
	let url = window.URL.createObjectURL(blob);
	downloadURI(url, name);
	window.URL.revokeObjectURL(url);
}

function downloadURI(uri, name) {
    let link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

Actualizar

function downloadURI(uri, name) {
    let link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}

function downloader(data, type, name) {
    let blob = new Blob([data], {type});
    let url = window.URL.createObjectURL(blob);
    downloadURI(url, name);
    window.URL.revokeObjectURL(url);
}

Respuesta #10

Ejemplo simple usando un iframe

function downloadURL(url) {
    var hiddenIFrameID = 'hiddenDownloader',
        iframe = document.getElementById(hiddenIFrameID);
    if (iframe === null) {
        iframe = document.createElement('iframe');
        iframe.id = hiddenIFrameID;
        iframe.style.display = 'none';
        document.body.appendChild(iframe);
    }
    iframe.src = url;
};

Luego simplemente llama a la función donde quieras:

downloadURL('path/to/my/file');

Artículos relacionados