Realice la función de finalización de descarga de archivos de monitoreo JS (resuelva el disparador de descarga de diferentes navegadores + el problema de que la base64url de una etiqueta es demasiado larga para descargar)

En términos generales, la descarga de nuestro archivo js usará window.location.href para ubicar la interfaz de back-end, el back-end genera el archivo y regresa, y luego el navegador lo descarga automáticamente. Este método es el más simple, pero es imposible recibir una notificación de una descarga exitosa. Cuando se genera y descarga un archivo grande, el tiempo es demasiado largo y el usuario puede repetir el clic de descarga, lo que sobrecargará el servidor.

Por lo tanto, debe enviar una solicitud de otra manera para monitorear la finalización de la descarga del archivo. Este método usa XMLHttpRequest para solicitar y usted puede monitorear la finalización de la descarga del archivo. Además, si desea monitorear la barra de progreso de descarga , puede utilizar la configuración del bucle de cookies hacia atrás. Este artículo solo analiza el método anterior para solicitar el progreso.

No mucho bb, solo empieza

Esta es la versión con la que comencé:

load = function() {
    
    
//填写你的下载时加载的提示
}
disload = function() {
    
    
//下载完成后触发,用来关闭提示框
}
getDownload = function(url) {
    
    
     load();
     var xhr = new XMLHttpRequest();
     xhr.open('GET', url, true);    // 也可用POST方式
     xhr.responseType = "blob";
     xhr.onload = function () {
    
    
         if (this.status === 200) {
    
    
             var blob = this.response;
             var reader = new FileReader();
             reader.readAsDataURL(blob);
             reader.onload = function (e) {
    
    
                 var headerName = xhr.getResponseHeader("Content-disposition");
                 var fileName = decodeURIComponent(headerName).substring(20);
                     var a = document.createElement('a');
                     a.download = fileName + ".xls";
                     a.href = e.target.result;
                     $("body").append(a);    // 修复firefox中无法触发click
                     a.click();
                     $(a).remove();
             };
             disload();
         }
     };
     xhr.send()
 };

Este principio es enviar una solicitud a través de XMLHttpRequest y usar FileReader para leer el contenido del archivo. La clave es establecer la etiqueta a, convertir el contenido del archivo del blob en base64 y ponerlo en el href de la etiqueta a, y simular hacer clic para descargar.

Pero cabe señalar que

  1. La descarga de la etiqueta a ha sido probada y solo funciona en los navegadores Google y Firefox, y no activa descargas en Edge e IE.
  2. Si usa base64 como la dirección URL de la etiqueta a, solo puede descargar archivos de hasta aproximadamente 2M debido a la limitación de longitud, y la descarga fallará si es mayor.

primera pregunta

Para navegadores como, por ejemplo, existe otra forma de activar la descarga.

 function dataURLtoBlob(dataurl) {
    
    
            var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
            while (n--) {
    
    
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], {
    
     type: mime });
        }
        
//e.target.result 正是上面代码中转换后的baseUrl,这种方法要转换为blob
var blob = dataURLtoBlob(e.target.result);
navigator.msSaveBlob(blob, fileName + ".xls");

Cabe destacar que navigator.msSaveBlob no existe en navegadores como Google. Aquí se soluciona el primer problema

segunda pregunta

La segunda pregunta realmente depende de la demanda. Para archivos muy pequeños, como iconos pequeños, puede usar base64 como dirección URL. Para otros archivos grandes, puede almacenar el archivo en la memoria y apuntarlo a la dirección de la memoria virtual.

var blob = dataURLtoBlob(e.target.result);
var a = document.createElement('a');
a.download = fileName + ".xls";
a.href = URL.createObjectURL(blob);
$("body").append(a);    // 修复firefox中无法触发click
a.click();
URL.revokeObjectURL(a.href);
$(a).remove();

URL.createObjectURL guarda un archivo en forma de blob y devuelve una URL para descargar.
El URL.revokeObjectURL continuación, se libera la memoria.
En este punto, los dos problemas se han resuelto. Se puede ver que base64 no se puede usar en absoluto para archivos grandes, y es mejor usar blob directamente. Por tanto, la versión final se puede obtener combinando:

Versión final

load = function() {
    
    
//填写你的下载时加载的提示
}
disload = function() {
    
    
//下载完成后触发,用来关闭提示框
}
getDownload = function(url) {
    
    
	load();
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);    // 也可用POST方式
    xhr.responseType = "blob";
    xhr.onload = function () {
    
    
        if (this.status === 200) {
    
    
            var blob = this.response;
            if (navigator.msSaveBlob == null) {
    
    
                var a = document.createElement('a');
                var headerName = xhr.getResponseHeader("Content-disposition");
                var fileName = decodeURIComponent(headerName).substring(20);
                a.download = fileName;
                a.href = URL.createObjectURL(blob);
                $("body").append(a);    // 修复firefox中无法触发click
                a.click();
                URL.revokeObjectURL(a.href);
                $(a).remove();
            } else {
    
    
                navigator.msSaveBlob(blob, fileName);
            }
        }
        disload();
    };
    xhr.send()
};

Supongo que te gusta

Origin blog.csdn.net/qq_35530005/article/details/103381205
Recomendado
Clasificación