Avoid Warning: POST Content-Length when uploading file

1

I'm trying to upload a file with PHP , I'm using the basics according to the PHP .

<form enctype="multipart/form-data" action="carga.php" method="POST">
    <input type="hidden" name="MAX_FILE_SIZE" value="2097152" />
    Subir archivo: <input name="archivo" type="file" />
    <input type="submit" value="Enviar fichero" />
</form>

And in the php I have:

$ruta = APP_BASEDIR . "/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";
}

But when I try to upload a file that is too big, it shows me: Warning: POST Content-Length of 83316897 bytes exceeds the limit of 8388608 bytes in Unknown on line 0

But it does not mark any line of code. The file I want to upload does not weigh 1Mb. It does not exceed the default php.ini limits that are 2Mb, so I did not modify anything. But I want the code to capture the error in case the file is too heavy. But how can I capture the error of the load if it does not tell me where it is? I even added

echo "Tamaño ".$_FILES['archivo']['size'];

But it shows nothing. The console displays this message for a few seconds and then cleans up:

    
asked by Piropeator 10.08.2018 в 08:52
source

1 answer

1

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 .

    
answered by 10.08.2018 / 10:52
source