'append' chamado em um objeto que não implementa a interface FormData

87

Estou tentando fazer upload de imagem com jquery e ajax. Mas uma coisa estranha aconteceu aqui. No console Log está sendo mostrado

TypeError: 'append' chamado em um objeto que não implementa a interface FormData.

Por favor, me diga o que eu fiz de errado aqui?

Script JS

var prosrc=$("#pro_pix img").last().attr("src");
$("#logoform").on('change',function(event){
var postData = new FormData(this);
$("#pro_pix img").last().hide();
$("#pro_pix img").first().show();
event.preventDefault();
$.ajax(
    {
        url : "/function/pro_pic_upload.php",
        type: "POST",
        data : postData,
        success:function(data, textStatus, jqXHR)
        {
        $("#pro_pix img").last().show();
        $("#pro_pix img").first().hide();
        $("#pro_pix h6").text(data);
        },
        error: function(jqXHR, textStatus, errorThrown)
        {
            //if fails     
        }
    });
});

Minha marcação HTML

 <div class="row">
    <!-- left column -->
    <div id="pro_pix" class="col-md-4 col-sm-6 col-xs-12">
      <div class="text-center">
        <img src="template/image/725.GIF" class="avatar img-circle img-thumbnail" style="display:none" alt="avatar">
        <img src="<?php echo $rowuser['profile_logo']; ?>" class="avatar img-circle img-thumbnail" alt="avatar">
        <h6>Upload a different photo...</h6>
        <form role="form" id="logoform" enctype="multipart/form-data">
        <input id="logo" name="logo" type="file" class="text-center center-block well well-sm">
        </form>
      </div>
    </div>

fonte
Olhe para a primeira questão relacionada: Como enviar objetos FormData com solicitações Ajax no jQuery? .
Felix Kling

Respostas:

184

para usar formdata com jquery você deve definir as opções corretas

$.ajax({
    url : "/function/pro_pic_upload.php",
    type: "POST",
    data : postData,
    processData: false,
    contentType: false,
    success:function(data, textStatus, jqXHR){
        $("#pro_pix img").last().show();
        $("#pro_pix img").first().hide();
        $("#pro_pix h6").text(data);
    },
    error: function(jqXHR, textStatus, errorThrown){
        //if fails     
    }
});

referência .ajax

processData (padrão: true)

Tipo: booleano

Por padrão, os dados passados ​​para a opção de dados como um objeto (tecnicamente, qualquer coisa diferente de uma string) serão processados ​​e transformados em uma string de consulta, ajustando-se ao tipo de conteúdo padrão "application / x-www-form-urlencoded" . Se você deseja enviar um DOMDocument ou outros dados não processados, defina esta opção como false.

Patrick Evans
fonte
Eu estou confuso. você pode me ajudar? Suponha que eu queira enviar um arquivo e uma string junto com um array. Suponha que em meu script eu queira enviar o arquivo de imagem e uma string com o nome de usuário. Como fazer isso? É possível fazer um json ou xml ou qualquer outro array para manter arquivo e string juntos? Eu sou iniciante. pode ser esta é a pergunta boba. eu preciso de sua ajuda ..
1
basta chamar o método append do objeto FormData para adicionar itens, ou seja:postData.append("name",value);
Patrick Evans
Observação para itens complexos como objetos, ou seja {cat:"meow",dog:"bark"}:, você deve usar JSON.stringify primeiro: postData.append("name",JSON.stringify(someObject));e analisar o json na extremidade do servidor
Patrick Evans
1
Não se esqueça: cache: false isso me deu problemas agora. Com tudo consertado.
Zri
Obrigado, estive paralisado neste problema durante a última hora!
user752746
34

Adicione estes dois parâmetros em seu AJAX para resolver seu problema:

processData: false,
contentType: false,
Sahriar rahman supto
fonte
Não se esqueça: cache: falseisso me deu problemas agora. Com tudo consertado.
Zri
@Zri, o que significa cache: false?
Fatih Mert Doğancan
Da documentação do jQuery: cache (padrão: true, false para dataType 'script' e 'jsonp') Tipo: Boolean Se definido como false, ele forçará as páginas solicitadas a não serem armazenadas em cache pelo navegador. Observação: definir o cache como falso só funcionará corretamente com solicitações HEAD e GET. Ele funciona anexando "_ = {timestamp}" aos parâmetros GET. O parâmetro não é necessário para outros tipos de solicitações, exceto no IE8 quando um POST é feito para uma URL que já foi solicitada por um GET.
Zri
1
@Zri Você pode estar usando uma GETsolicitação. O cache:falsenão funcionará corretamente para POSTsolicitação. Como você mencionou no comentário acima, funciona apenas para solicitações HEADe GET. E FormDataé usado para enviar dados de um formulário que deve ser um em POSTvez de GET. Portanto, sugiro que você sempre use o POST para enviar dados do formulário.
Lucky
2

Você deve definir este parâmetro na chamada ajax:

enctype: 'multipart/form-data'
Krupal Patel
fonte
2

Adicionando:

processData: false,
contentType: false,

vai certamente ajudar com o arquivo, um aparte disso é que se você estiver fazendo qualquer tipo de repasse de erros ou mensagens de sucesso para a página, você vai querer usar o json para tornar sua vida mais fácil.

exemplo:

dataType: 'json',

isso ajudará a analisar suas respostas. Sem ele, ele gerará um erro.

modnarrandom
fonte
0

Apenas edite sua linha:

var postData = new FormData(this);

para:

var postData = new FormData($(this));
e sadeghi
fonte