Validação de tamanho de upload de arquivo JavaScript

254

Existe alguma maneira de verificar o tamanho do arquivo antes de enviá-lo usando JavaScript?

Arca
fonte

Respostas:

327

Sim , há um novo recurso do W3C suportado por alguns navegadores modernos, a API de arquivos . Ele pode ser usado para esse fim, e é fácil testar se é suportado e recorrer (se necessário) a outro mecanismo, se não for.

Aqui está um exemplo completo:

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Show File Data</title>
<style type='text/css'>
body {
    font-family: sans-serif;
}
</style>
<script type='text/javascript'>
function showFileSize() {
    var input, file;

    // (Can't use `typeof FileReader === "function"` because apparently
    // it comes back as "object" on some browsers. So just see if it's there
    // at all.)
    if (!window.FileReader) {
        bodyAppend("p", "The file API isn't supported on this browser yet.");
        return;
    }

    input = document.getElementById('fileinput');
    if (!input) {
        bodyAppend("p", "Um, couldn't find the fileinput element.");
    }
    else if (!input.files) {
        bodyAppend("p", "This browser doesn't seem to support the `files` property of file inputs.");
    }
    else if (!input.files[0]) {
        bodyAppend("p", "Please select a file before clicking 'Load'");
    }
    else {
        file = input.files[0];
        bodyAppend("p", "File " + file.name + " is " + file.size + " bytes in size");
    }
}

function bodyAppend(tagName, innerHTML) {
    var elm;

    elm = document.createElement(tagName);
    elm.innerHTML = innerHTML;
    document.body.appendChild(elm);
}
</script>
</head>
<body>
<form action='#' onsubmit="return false;">
<input type='file' id='fileinput'>
<input type='button' id='btnLoad' value='Load' onclick='showFileSize();'>
</form>
</body>
</html>

E aqui está em ação. Tente isso com uma versão recente do Chrome ou Firefox.


Ligeiramente fora de tópico, mas: Observe que a validação do lado do cliente não substitui a validação do lado do servidor. A validação do lado do cliente visa puramente proporcionar uma experiência melhor ao usuário. Por exemplo, se você não permitir o upload de um arquivo com mais de 5 MB, poderá usar a validação do lado do cliente para verificar se o arquivo escolhido pelo usuário não tem mais de 5 MB e fornecer uma boa mensagem amigável, se for o caso. (para que eles não gastem todo esse tempo enviando apenas para jogar o resultado fora no servidor), mas você também deve impor esse limite no servidor, pois todos os limites do cliente (e outras validações) podem ser contornados.

TJ Crowder
fonte
12
+1 para "todos os limites do lado do cliente (e outras validações) podem ser contornados". Isso é verdade também para aplicativos de frontend de banco de dados "nativos" / "compilados". E não coloque as senhas de acesso ao banco de dados no seu código compilado, nem mesmo "criptografado" (com uma senha que também está no código - vi isso recentemente).
Masterxilo 12/0118
117

Usando jquery:

<form action="upload" enctype="multipart/form-data" method="post">

    Upload image:
    <input id="image-file" type="file" name="file" />
    <input type="submit" value="Upload" />

    <script type="text/javascript">
        $('#image-file').bind('change', function() {
            alert('This file size is: ' + this.files[0].size/1024/1024 + "MB");
        });
    </script>

</form>
Ben
fonte
2
@ ipd, alguma chance de um fallback do IE8? (Eu estou me odiando, mesmo para mencionar IE)
Asher
2
Este funciona, mas funciona para vários arquivos também?
Ingus 15/08/19
4
Deveria ser MiBse você calcular para a base de 1024.
slartidan
69

Funciona para elemento de arquivo dinâmico e estático

Solução Somente Javascript

function ValidateSize(file) {
        var FileSize = file.files[0].size / 1024 / 1024; // in MB
        if (FileSize > 2) {
            alert('File size exceeds 2 MB');
           // $(file).val(''); //for clearing with Jquery
        } else {

        }
    }
 <input onchange="ValidateSize(this)" type="file">

Arun Prasad ES
fonte
1
Boa resposta. Eu estava tendo o mesmo problema, mas sua solução funcionou para mim :)
Dipankar Das
1
NB OP editou o post para o código agora está correta, usando a sizepropriedade
UsAndRufus
1
Obrigado pela resposta, eu estava quase fazendo o mesmo, mas com uma alteração. $(obj).files[0].size/1024/1024; Mas mudei paraobj.files[0].size/1024/1024;
shakir Baba
Existe uma maneira de estender isso para validação de largura e altura? (deixando um "ficheiro" como o ponto de partida e assumindo que se refere a uma imagem)
jlmontesdeoca
@jlmontesdeoca Acho que você pode ler o arquivo com a ajuda do canvas e obter sua altura e largura aqui.
Arun Prasad ES
14

Não Sim, usando a API de arquivos em navegadores mais recentes. Veja a resposta de TJ para detalhes.

Se você também precisa oferecer suporte a navegadores mais antigos, será necessário usar um carregador baseado em Flash como SWFUpload ou Uploadify para fazer isso.

A demonstração dos recursos do SWFUpload mostra como a file_size_limitconfiguração funciona.

Observe que isso (obviamente) precisa do Flash, e a maneira como ele funciona é um pouco diferente dos formulários normais de upload.

Pekka
fonte
14

É bem simples.

            var oFile = document.getElementById("fileUpload").files[0]; // <input type="file" id="fileUpload" accept=".jpg,.png,.gif,.jpeg"/>

            if (oFile.size > 2097152) // 2 mb for bytes.
            {
                alert("File size must under 2mb!");
                return;
            }
Hasan Atum Oruç
fonte
Melhor resposta. doce e simples ... :)
A. Sinha
12

Se você estiver usando a validação do jQuery, poderá escrever algo como isto:

$.validator.addMethod(
    "maxfilesize",
    function (value, element) {
        if (this.optional(element) || ! element.files || ! element.files[0]) {
            return true;
        } else {
            return element.files[0].size <= 1024 * 1024 * 2;
        }
    },
    'The file size can not exceed 2MB.'
);
Nikolaos Georgiou
fonte
4

Eu fiz algo assim:

$('#image-file').on('change', function() {
 var numb = $(this)[0].files[0].size/1024/1024;
numb = numb.toFixed(2);
if(numb > 2){
alert('to big, maximum is 2MB. You file size is: ' + numb +' MB');
} else {
alert('it okey, your file has ' + numb + 'MB')
}
        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<input type="file" id="image-file">

kibus90
fonte
Isto diz javascript, JQuery não está nas tags
Olá234 29/02
3

Eu uso uma função Javascript principal que eu encontrei no site da Mozilla Developer Network https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications , juntamente com outra função com o AJAX e alterada de acordo com minhas necessidades. Ele recebe um ID do elemento do documento referente ao local no meu código html onde desejo escrever o tamanho do arquivo.

<Javascript>

function updateSize(elementId) {
    var nBytes = 0,
    oFiles = document.getElementById(elementId).files,
    nFiles = oFiles.length;

    for (var nFileId = 0; nFileId < nFiles; nFileId++) {
        nBytes += oFiles[nFileId].size;
    }
    var sOutput = nBytes + " bytes";
    // optional code for multiples approximation
    for (var aMultiples = ["K", "M", "G", "T", "P", "E", "Z", "Y"], nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
        sOutput = " (" + nApprox.toFixed(3) + aMultiples[nMultiple] + ")";
    }

    return sOutput;
}
</Javascript>

<HTML>
<input type="file" id="inputFileUpload" onchange="uploadFuncWithAJAX(this.value);" size="25">
</HTML>

<Javascript with XMLHttpRequest>
document.getElementById('spanFileSizeText').innerHTML=updateSize("inputFileUpload");
</XMLHttpRequest>

Felicidades

Jose Gaspar
fonte
3

Mesmo que a pergunta seja respondida, eu queria postar minha resposta. Pode ser útil para futuros espectadores. Você pode usá-lo como no código a seguir.

<input type="file" id="fileinput" />
<script type="text/javascript">
  function readSingleFile(evt) {
    //Retrieve the first (and only!) File from the FileList object
    var f = evt.target.files[0]; 
    if (f) {
      var r = new FileReader();
      r.onload = function(e) { 
          var contents = e.target.result;
        alert( "Got the file.n" 
              +"name: " + f.name + "n"
              +"type: " + f.type + "n"
              +"size: " + f.size + " bytesn"
              + "starts with: " + contents.substr(1, contents.indexOf("n"))
        ); 
        if(f.size > 5242880) {
               alert('File size Greater then 5MB!');
                }


      }
      r.readAsText(f);
    } else { 
      alert("Failed to load file");
    }
  }
Lemon Kazi
fonte
3

O exemplo de JQuery fornecido neste segmento estava extremamente desatualizado e o google não ajudou em nada, então aqui está minha revisão:

 <script type="text/javascript">
        $('#image-file').on('change', function() {
            console.log($(this)[0].files[0].name+' file size is: ' + $(this)[0].files[0].size/1024/1024 + 'Mb');
        });
    </script>
acena
fonte
1

Você pode experimentar este fineuploader

Funciona bem no IE6 (e acima), Chrome ou Firefox

anson
fonte
3
O Fine Uploader não pode validar o tamanho do arquivo no IE9 e mais antigo, pois o suporte à API de arquivos não é suportado. O IE10 é a primeira versão do Internet Explorer que suporta a API de arquivos.
Raio Nicholus
-2

Se você definir o 'Modo Documento' como 'Padrões', poderá usar o método 'tamanho' de javascript simples para obter o tamanho do arquivo carregado.

Defina o Ie 'Document Mode' para 'Standards':

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

Em seguida, use o método javascript 'size' para obter o tamanho do arquivo enviado:

<script type="text/javascript">
    var uploadedFile = document.getElementById('imageUpload');
    var fileSize = uploadedFile.files[0].size;
    alert(fileSize); 
</script>

Funciona para mim.

Lilla
fonte
1
Isso não funcionará no IE9 ou mais antigo, independentemente das metatags adicionadas.
Raio Nicholus