Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

dinhografo

[Resolvido] Função serialize() do jQuery não retorna campo file

Recommended Posts

Com o código abaixo eu consigo recuperar todos os campos tipo text, textarea,..., porém, o campo do tipo file ele não retorna, já tentei vários métodos mas não consegui.

$('form#agenda').live('submit',function(e){
e.preventDefault();
var action = $(this);
//Apenas para mostrar no console os retornos do envio
console.log(action.serialize());
$.ajax({
	url: action.attr("action"),
	type: 'post',
	data: action.serialize(),//serializeArray() é melhor para ser debugado, mas tem o mesmo resultado
	success: function( response ){
		var data = $( '<div>'+response+'</div>' ).find('#conteudo').html();
		conteudo.html(data);	
	}
});
});

O formulário é esse:

<form method="post" id="agenda" action="?pag=agenda.php&fazer=adicionar" enctype="multipart/form-data">
   <input type="hidden" name="acao" id="acao" value="Adicionar">
   Título: 
   <input type="text" name="titulo" id="titulo" size="60" value="Titulo">  
   Data: 
   <input type="text" name="data" id="data" size="11" maxlength="10" value="<?php echo $data;?>"><br>  
   URL: <input type="text" name="url" id="url" size="60" value="http://localhost/admin/agenda/"><br>  
   Foto: <br><input name="foto" id="foto" type="file" value="" /> <br><!---->
   Descrição: <br>
   <textarea name="descricao" cols="74" rows="10">Minha Descrição aqui</textarea><br>  
   <input type="submit" value="Adicionar" />
</form>

A página php que pega esses valores tá normal, pois se o form não for enviado via $.ajax() ele captura todos os campos sem problema.

 

Como eu disse é só o campo (<input name="foto" id="foto" type="file" value="" />) que o $.ajax() não está serializando corretamente com o serialize(), com o console.log(action.serialize()) se pode verificar.

 

Alguma idéia de como retornar esse campo do tipo file pelo $.ajax()?

Obrigado pela atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

não dá.

 

ajax não envia arquivos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Cara esse meu ajax só manda as os campos por POST(serializado) para uma página PHP fazer o upload, página essa que também é responsável por pegar esses valores e gravar no DB, a bronca é que o campo do tipo file não vai nessa serialização

Eu imaginei algo do tipo: o campo file gerar um caminho para um campo hidden com outro nome e esse campo hidden passar por POST para o meu script PHP para que ele por referencia possa fazer o upload, mas não sei se isso vai dar certo.

 

Qualquer ajuda é bem vinda.

Obrigado pela atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Eu imaginei algo do tipo: o campo file gerar um caminho para um campo hidden com outro nome e esse campo hidden passar por POST para o meu script PHP para que ele por referencia possa fazer o upload, mas não sei se isso vai dar certo.

 

Não tem como, o PHP não pode acessar o computador do cliente para 'puxar' o arquivo para download, mesmo que você coloque o endereço.

O upload de arquivos tem que ser 'empurrado' do cliente para o servidor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

A única coisa que tenho certeza é que a função serialize() não está retornando o campo do tipo file, os outros estão todos corretos e gravando no DB pelo código php que faz essa insersão(isso sem refresh).

 

1 - O código que eu postei no inicio funciona com todos os campos, menos o <input name="foto" id="foto" type="file" value="" />

2 - O código PHP também está funcionando pois se eu enviar normalmente sem o uso do método $.ajax, $.post, ..., o PHP faz a inserção no DB e o upload sem bronca.

 

Acredito que a bronca esteja na função serialize() do jQuery, pois, quem testar o código que eu postei perceberá(no console) que o campo do tipo file é o único que não é serializado e não dá retorno, e se não há a variável $_FILES['foto'] retornada pelo form enviado o PHP não faz o upload.

 

Obrigado pela atenção.

Compartilhar este post


Link para o post
Compartilhar em outros sites

vou falar denovo:

 

não dá. Ok ?

 

o serialize(), nunca vai te enviar o campo type="file", pq ajax, não envia arquivos.

O "problema", não é o .serialize(), mas sim a linguagem, que não suporta isso.

 

 

Por motivos de segurança, a linguagem javascript, não tem permissão para manipular arquivos. Entendeu agora ?

Se você quiser fazer um upload assincrono, só existem 2 opções:

 

-> usar flash, ou

-> usar um iframe escondido.

 

 

Com javascript não é possível.

Espero que agora você compreenda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ou tem uma 3ª opção que é um plugin(http://jquery.malsup.com/form/) que esse sim envia todos os campos(incluindo os do tipo file) por post no meu caso ficou assim:

$(':submit').live('click',function(e){
       e.preventDefault();
       var action = $(this).parent();//recupera o valor do pai(meu form #agenda) do botão submit       
       $.ajax({                
               success: function( response ){
                       action.ajaxSubmit();    
               }
       });
});

 

Na maioria das vezes eu sou do tipo: Se funcionou não deixa!

Mas nesse caso é intrigante saber que esse plugin retorna todos os campos por post e o serialize() não.

 

Há não esqueça de por o plugin no head: <script type="text/javascript" src="js/jquery.form.js"></script>

Compartilhar este post


Link para o post
Compartilhar em outros sites

ok, agora você quer entender oque o plugin fez?

 

linha 203 dele:

$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');

ou seja, a minha segunda opção disfarçada.

 

 

ou seja, o plugin não fez milagre, apenas enviou pelo iframe, e te "enganou".

Não tem mistério e nem nada intrigante qndo você sabe como funciona.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, parece que é isso mesmo.

 

Não sou lá essas coisas em javascript, por isso não vou entrar nessa pq é de competência de quem sabe mais do que eu(o que é bem fácil, rsrsrs), mas comparando os dois envios no console do FF dá pra perceber que pelo 1º script o form é enviado como application/x-www-form-urlencoded mas para enviar um arquivo tem que ser multipart/form-data, isso já tem como parametro no form original só que o serialize() não recupera o valor de enctype do form, e parece que a bronca toda está aí.

 

Já o pluguin não envia esse parametro, mas sim um Content-Disposition: form-data; name="NOME_DO_CAMPO" para cada campo e parece que ele converte a imagem para um código utf8 ou algo assim(sei lá), e isso vai comprometer o desempenho de códigos maiores que esse meu.

 

Acredito que se houver como passar o form como multipart/form-data para ser serializado não vai dar bronca no script.

Compartilhar este post


Link para o post
Compartilhar em outros sites

então cara.. mas olha a aba REDE do Firebug.

 

você vai ver q o form de upload, não faz XHR, mas sim um POST normal.(pelo iframe, ou seja, o js não envia nada)

 

 

 

Since it is not possible to upload files using the browser's XMLHttpRequest object, the Form Plugin uses a hidden iframe element to help with the task.

http://jquery.malsup.com/form/#file-upload

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom eu me virei a tarde toda e consegui adicionar um script para pegar todos os campos do form:

var params = {};
jQuery.each(action.find('input'), function(index,value) {
params[value.name] = value.value;
});

e bastou que eu trocar data:action.serialize() por data: param para pegar realmente todos os campos do form, depois eu adicionei a linha contentType: 'multipart/form-data', e arequisição ajax deu um sinal de que iria funcionar, porem o sinal foi falso, eu li a docomentação da jQuery, mas meu ingles é, ou melhor não é, e a tradução do google não ajuda muito, o que deu pra entender é que além de tocar o cabeçalho da requisição vai ser preciso fazer uma série de rotinas para encodar em base64, passar por um iframe, ..., e isso tudo o plugin já faz, por isso é melhor deixar esse plugin trabalhar ou ser muito fera em javascript para escrever uma rotina só pra isso, rsrsrs.

 

Agora com tudo de pesquisa que fiz, e mais os testes realizados, eu achei que o código

var params = {}; 
jQuery.each(jQuery('form').find('input'), function(index,value) {
params[value.name] = value.value;
});

é mais rápido(uns 3ms em média) que o serialize() e serializeArray(), e me pareceu mais seguro também já que não dá erros e nem deixa campo algum sem retorno.

 

O código original está nos comentários da documentação da api, porém eu revirei tanto que não sei exatamente onde é que está.

 

Insistência é uma coisa boa e sempre traz bons frutos para o trabalho.

Teimosia é ruin e atrasa a o desenvolvimento pessoal e proficional.

 

Agradeço a atenção de todos.

Compartilhar este post


Link para o post
Compartilhar em outros sites

<script type="text/javascript">  
$("#form_oferta").submit(function(event) { 
                   var dados = $( form ).serialize(); 
                   $.ajax({  
                       type: "POST", 
                       contentType:attr( "enctype", "multipart/form-data" ),
                       url: "<?php echo site_url(); ?>adm/oferta_insert",  
                       data: dados,  
                       success: function( data )  
                       {  
                           alert( data );  
                       }  
                   });  

                   return false;  
               }   
</script>

Acresentando contentType:attr( "enctype", "multipart/form-data" ) ao script você conseguei enviar arquivos por ajax jquery.

 

http://pastebin.com/aMEZmV3S

Compartilhar este post


Link para o post
Compartilhar em outros sites
<script type="text/javascript">  
$("#form_oferta").submit(function(event) { 
                    var dados = $( form ).serialize(); 
                    $.ajax({  
                        type: "POST", 
                        contentType:attr( "enctype", "multipart/form-data" ),
                        url: "<?php echo site_url(); ?>adm/oferta_insert",  
                        data: dados,  
                        success: function( data )  
                        {  
                            alert( data );  
                        }  
                    });  
              
                    return false;  
                }   
 </script>
Acresentando contentType:attr( "enctype", "multipart/form-data" ) ao script você conseguei enviar arquivos por ajax jquery.

 

http://pastebin.com/aMEZmV3S

 

 

tentei assim e tenho o erro "attr is not defined"

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.