Obter dados da entrada de arquivo no JQuery

136

Na verdade, tenho uma entrada de arquivo e gostaria de recuperar os dados Base64 do arquivo.

Eu tentei:

$('input#myInput')[0].files[0] 

para recuperar os dados. Mas ele fornece apenas o nome, o comprimento, o tipo de conteúdo, mas não os dados em si.

Na verdade, eu preciso desses dados para enviá-los ao Amazon S3

Já testei a API e, quando envio os dados através do formulário html com o tipo de codificação "multipart / form-data", ele funciona.

Eu uso este plugin: http://jasny.github.com/bootstrap/javascript.html#fileupload

E esses plugins me fornecem uma visualização da imagem e eu recupero dados no atributo src da visualização da imagem. Mas quando eu envio esses dados para o S3, eles não funcionam. Talvez eu precise codificar os dados como "multipart / form-data", mas não sei por que.

Existe uma maneira de recuperar esses dados sem usar um formulário html?

kschaeffler
fonte
Para ter conteúdo, você precisará enviá-lo de alguma forma (iframe, ajax, flash ou forma tradicional).
Brad Christie
O arquivo deve ser carregado primeiro no servidor.
Sven van Zoelen 5/09/12
3
Não necessariamente, se o navegador suporta a nova API de arquivos (veja html5rocks.com/en/tutorials/file/dndfiles )
devnull69
Na verdade, estou usando este plugin jasny.github.com/bootstrap/javascript.html#fileupload e posso obter uma visualização do arquivo para que os dados estejam em algum lugar.
kschaeffler
nesse caso, os "dados" estarão no servidor. Você vai ter que enviar os dados para o cliente (navegador) antes que você possa acessá-lo via JavaScript / jQuery
devnull69

Respostas:

134

Você pode tentar a API FileReader. Faça algo parecido com isto:

<!DOCTYPE html>
<html>
  <head>
    <script>        
      function handleFileSelect()
      {               
        if (!window.File || !window.FileReader || !window.FileList || !window.Blob) {
          alert('The File APIs are not fully supported in this browser.');
          return;
        }   
      
        var input = document.getElementById('fileinput');
        if (!input) {
          alert("Um, couldn't find the fileinput element.");
        }
        else if (!input.files) {
          alert("This browser doesn't seem to support the `files` property of file inputs.");
        }
        else if (!input.files[0]) {
          alert("Please select a file before clicking 'Load'");               
        }
        else {
          var file = input.files[0];
          var fr = new FileReader();
          fr.onload = receivedText;
          //fr.readAsText(file);
          //fr.readAsBinaryString(file); //as bit work with base64 for example upload to server
          fr.readAsDataURL(file);
        }
      }
      
      function receivedText() {
        document.getElementById('editor').appendChild(document.createTextNode(fr.result));
      }           
      
    </script>
  </head>
  <body>
    <input type="file" id="fileinput"/>
    <input type='button' id='btnLoad' value='Load' onclick='handleFileSelect();' />
    <div id="editor"></div>
  </body>
</html>

Sark
fonte
Ei, eu tentei sua solução e isso funciona. Eu recuperei as informações, mas elas não estão bem codificadas. Para um arquivo, recebo em \xc3\xbf\xc3vez de obter essa codificação \xff\xd8\xffpara os 3 primeiros caracteres da minha imagem. O que devo usar para obter a segunda codificação da minha foto?
kschaeffler
@kschaeffler tente fr.readAsDataURL (arquivo); esta é a função de leitura de dados Base64, mas ainda não testei.
Sark
na verdade, essa função não me fornece dados suficientes. isso já é o que tenho da visualização que uso no plug-in jasny.github.com/bootstrap/javascript.html#fileupload. Eu acho que os dados que recuperar não são Base64 codificado e este é o problema, mas não tenho certeza
kschaeffler
Eu realmente preciso as mesmas codificar dados que eu recuperar quando eu posto através de formulário HTML com o "multipart / form-data" o tipo de codificação
kschaeffler
156

elemento do arquivo de entrada:

<input type="file" id="fileinput" />

obter arquivo:

var myFile = $('#fileinput').prop('files');
Morilog
fonte
12
Solução perfeita! obrigado. Melhoria para upload único, índice 0. var myFile = $ ('# fileinput'). Prop ('files') [0];
polras 23/12/16
Excelente, consegui meu script trabalhando com o Cloudinary sem precisar enviar um formulário. Arraste, solte, faça o upload :)
Andy
Isso é exatamente o que eu precisava.
Amete Blessed
Ótima resposta !! então você pode mover a variável com$('.myClass').prop('files', myFile );
sempre-aluno
54

Criei um objeto de dados do formulário e anexei o arquivo:

var form = new FormData(); 
form.append("video", $("#fileInput")[0].files[0]);

e eu tenho:

------WebKitFormBoundaryNczYRonipfsmaBOK
Content-Disposition: form-data; name="video"; filename="Wildlife.wmv"
Content-Type: video/x-ms-wmv

nos cabeçalhos enviados. Posso confirmar que isso funciona porque meu arquivo foi enviado e armazenado em uma pasta no meu servidor. Se você não souber como usar o objeto FormData, existe alguma documentação online, mas não muita. Exploração de objeto de dados de formulário da Mozilla

mark.inman
fonte
37

Html:

<input type="file" name="input-file" id="input-file">

jQuery:

var fileToUpload = $('#input-file').prop('files')[0];

Queremos obter apenas o primeiro elemento, porque prop ('files') retorna array.

cerbin
fonte
16

input elemento, do tipo file

<input id="fileInput" type="file" />

Em sua inputalteração, use o FileReaderobjeto e leia sua inputpropriedade de arquivo:

$('#fileInput').on('change', function () {
    var fileReader = new FileReader();
    fileReader.onload = function () {
      var data = fileReader.result;  // data <-- in this var you have the file data in Base64 format
    };
    fileReader.readAsDataURL($('#fileInput').prop('files')[0]);
});

O FileReader carregará seu arquivo e fileReader.resultvocê terá os dados do arquivo no formato Base64 (também o tipo de conteúdo do arquivo (MIME), texto / sem formatação, imagem / jpg, etc)

Carlos B. Flores
fonte
9

API FileReader com jQuery, exemplo simples.

( function ( $ ) {
	// Add click event handler to button
	$( '#load-file' ).click( function () {
		if ( ! window.FileReader ) {
			return alert( 'FileReader API is not supported by your browser.' );
		}
		var $i = $( '#file' ), // Put file input ID here
			input = $i[0]; // Getting the element from jQuery
		if ( input.files && input.files[0] ) {
			file = input.files[0]; // The file
			fr = new FileReader(); // FileReader instance
			fr.onload = function () {
				// Do stuff on onload, use fr.result for contents of file
				$( '#file-content' ).append( $( '<div/>' ).html( fr.result ) )
			};
			//fr.readAsText( file );
			fr.readAsDataURL( file );
		} else {
			// Handle errors here
			alert( "File not selected or browser incompatible." )
		}
	} );
} )( jQuery );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="file" />
<input type='button' id='load-file' value='Load'>
<div id="file-content"></div>

Para ler como texto ... descomente a //fr.readAsText(file);linha e o comentáriofr.readAsDataURL(file);

shramee
fonte
0
 <script src="~/fileupload/fileinput.min.js"></script>
 <link href="~/fileupload/fileinput.min.css" rel="stylesheet" />

Faça o download dos arquivos acima denominados fileinput e adicione o caminho na sua página de índice.

<div class="col-sm-9 col-lg-5" style="margin: 0 0 0 8px;">
<input id="uploadFile1" name="file" type="file" class="file-loading"       
 `enter code here`accept=".pdf" multiple>
</div>

<script>
        $("#uploadFile1").fileinput({
            autoReplace: true,
            maxFileCount: 5
        });
</script>
Amit Rana
fonte