The use of the form field MAX_FILE_SIZE
is used to limit the size of the files on the server side, when the data has been sent. That is, the size is not checked before sending, so you will not prevent the warning if you exceed the maximum allowed by PHP (default, 8 MiB).
To check the size and cancel the shipment you must use a check from the client side by using the FileList
which is available in HTML5 in the fields <input type="file" />
.
Each FileList
element is an instance of File
that has the following properties (including those inherited from Blob
):
File.lastModifiedDate
The last Date(fecha)
modification of the file referenced by the File
object.
File.name
The name of the file referenced by the object File
.
File.fileName (Obsolete Gecko 7.0)
The name of the file referenced by the object File
.
File.fileSize (Obsolete Gecko 7.0)
The size of the file referenced in bytes.
Blob.size
The size, in bytes, of the data contained in the Blob
object.
Blob.type
A string ( String
) indicating the MIME type of the data contained in Blob
. If the type is unknown, this string will be empty.
So with the following lines you could check if the size of the only file you have on your form is greater than the one marked by the tag:
let archivo = form.querySelector('input[name="archivo"]').files[0].size;
let maximo = form.querySelector('input[name="MAX_FILE_SIZE"]').value;
if (archivo > maximo) {
alert('Máximo superado');
}
You can add this check in the send event of the form to avoid sending larger files of the limit or in the event of change.
Here is a proof of concept that checks both the individual size of each file in the form and the total of it:
<?php
if (count($_FILES) > 0) {
$ruta = __DIR__ . "/cargas/";
$fichero_subido = $ruta . basename($_FILES['archivo']['name']);
if (move_uploaded_file($_FILES['archivo']['tmp_name'], $fichero_subido)) {
echo "El fichero es válido y se subió con éxito.\n";
} else {
echo "¡Posible ataque de subida de ficheros!\n";
}
}
?><form enctype="multipart/form-data" action="carga.php"
method="POST" onsubmit="return comprobar(this)">
<input type="hidden" name="MAX_FILE_SIZE" value="2097152" />
Subir archivo: <input name="archivo" type="file" />
<input type="submit" value="Enviar fichero" />
</form>
<script>
function comprobar(form) {
let maximo = form.querySelector('input[name="MAX_FILE_SIZE"]'), total = 0;
/* Si no está la etiqueta MAX_FILE_SIZE
creamos un máximo por defecto */
if (maximo === null) {
maximo = 2 * 1024 * 1024;
console.log('Máximo (por defecto):', maximo);
} else {
maximo = parseInt(maximo.value);
console.log('Máximo (etiqueta):', maximo);
}
let fallidos = [], compatible = true;
/* Comprobamos cada archivo del formulario */
form.querySelectorAll('input[type="file"]').forEach(function(archivos) {
/* Si está disponible en el navegador, hacemos uso de FileList/File
para comprobar el tamaño de los archivos */
if (archivos.files) {
for (let i = 0; i < archivos.files.length; i++) {
/* Actualizamos el total del formulario completo
(si hay varios archivos) */
total += archivos.files[i].size;
if (archivos.files[i].size > maximo) {
fallidos.push(archivos.files[i]);
}
}
} else {
/* Marcamos la compatibilidad como fallida */
compatible = false;
}
});
/* Comprobamos la compatibilidad con HTML5 */
if (compatible === false) {
console.log(
'ADVERTENCIA: Su navegador no es compatible con HTML5.',
'No se comprobará el tamaño de los archivos.'
);
/* Aún así permitimos el envío del formulario, saldrá
la advertencia de PHP si se supera el máximo */
return true;
}
/* Si no ha sido rechazado ningún archivo y el total está
en el margen establecido, enviamos el formulario */
if (fallidos.length == 0 && total <= maximo) {
console.log('Todos los tamaños están en márgenes correctos');
return true;
} else {
let mensaje = '';
if (fallidos.length > 0) {
mensaje = 'Los siguientes archivos superan el máximo:\n';
fallidos.forEach(function(archivo){
mensaje += '- "' + archivo.name + '" ('
+ parseInt(archivo.size / 1024) + ' KiB)\n';
});
} else if (total > maximo) {
mensaje += 'El máximo total ha sido superado ('
+ parseInt(total / 1024) + ' KiB)';
}
console.log(mensaje);
alert(mensaje);
}
/* Si hemos llegado a este punto debemos cancelar el envío */
return false;
}
</script>
NOTE: You should know that the HTML5 File
API is available in the current browsers, the following versions are obsolete (basic support / full support):
- Internet Explorer < 10
- Google Chrome < 5/21
- Firefox < 4/13
- Opera < 11.10 / 12.10
- Safari < 5.1 / 6
In unsupported browsers the submission will be made, appearing the PHP warning of limit exceeded.
My previous answer is saved here .