La forma más simple y robusta que he hecho en el pasado es simplemente apuntar a una etiqueta iFrame oculta con su formulario; luego se enviará dentro del iframe sin volver a cargar la página.
Es decir, si no desea utilizar un complemento, JavaScript o cualquier otra forma de "magia" que no sea HTML. Por supuesto, puedes combinar esto con JavaScript o lo que tienes ...
<form target="iframe" action="" method="post" enctype="multipart/form-data">
<input name="file" type="file" />
<input type="button" value="Upload" />
</form>
<iframe name="iframe" id="iframe" style="display:none" ></iframe>
También puede leer el contenido del iframe onLoad
para errores del servidor o respuestas exitosas y luego enviarlo al usuario.
Chrome, iFrames y onLoad
-note- solo necesita seguir leyendo si está interesado en cómo configurar un bloqueador de UI al cargar / descargar
Actualmente, Chrome no activa el evento onLoad para el iframe cuando se usa para transferir archivos. Firefox, IE y Edge activan el evento de carga para las transferencias de archivos.
La única solución que encontré que funciona para Chrome fue usar una cookie.
Para hacer eso básicamente cuando se inicia la carga / descarga:
- [Lado del cliente] Inicie un intervalo para buscar la existencia de una cookie
- [Lado del servidor] Haga lo que necesite con los datos del archivo
- [Lado del servidor] Establecer cookie para el intervalo del lado del cliente
- [Cliente] El intervalo ve la cookie y la usa como el evento onLoad. Por ejemplo, puede iniciar un bloqueador de UI y luego onLoad (o cuando se hace una cookie) elimina el bloqueador de UI.
Usar una cookie para esto es feo pero funciona.
Hice un complemento jQuery para manejar este problema para Chrome al descargar, puedes encontrar aquí
https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js
El mismo principio básico se aplica también a la carga.
Para usar el descargador (incluya el JS, obviamente)
$('body').iDownloader({
"onComplete" : function(){
$('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
}
});
$('somebuttion').click( function(){
$('#uiBlocker').css('display', 'block'); //block the UI
$('body').iDownloader('download', 'htttp://example.com/location/of/download');
});
Y en el lado del servidor, justo antes de transferir los datos del archivo, cree la cookie
setcookie('iDownloader', true, time() + 30, "/");
El complemento verá la cookie y luego activará la onComplete
devolución de llamada.