Error sending Upload with Ajax

Asked

Viewed 1,662 times

11

I am trying to send a file via Upload to a certain folder but I am not able to do and not understanding the error being accused by the script, I will try to be as clear as possible in the description of the problem. This is the excerpt from the Upload validation and submission form:

// INÍCIO GRAVA UPLOAD
function GravaUpload(event) {

    event.preventDefault();

    var params = $('#frmUpload').serializeArray();  
    $("#resultado-upload").html('<img src="../_imagens/ajax-loader.gif" alt="Enviando..." />');

    $.post(
        'GravaUpload.php',
        params,
        function( json, textStatus, jQxhr )
        {               
            if (json.status != "ERRO") {
                var msg = '<div class="alert alert-info" role="alert">' + json.msg + '</div>' ;
            } else {
                var msg = '<div class="alert alert-danger" role="alert">' + json.msg + '</div>' ;
            }
            $("#resultado-upload").html(msg);
        },
        'json'
    )
    .fail(function( jqXhr, textStatus, errorThrown ){

        console.log( jqXhr, textStatus, errorThrown );
        try {
            var json = $.parseJSON(jqXHR.responseText);
            var msg = '<div class="alert alert-danger" role="alert">' + json.errorMessage + '.</div>';
            $("#resultado-upload").html(msg);
        } catch(e) { 
            var msg = '<div class="alert alert-danger" role="alert">Ocorreu um erro ao tentar manipular os dados. Verifique sua conexão com o banco de dados.</div>';
            $("#resultado-upload").html(msg);
        }
    });
}  // FIM GRAVA DETALHES DO CONTRATO

$(document).ajaxError(function (e, data, settings, exception) { 
    console.log(e, data, settings, exception);
});

$(document).ready(function() {

    //***** Validações de campos e envio do formulario por AJAX
    $("#frmUpload").validate({
        rules: {
            fileUpload: {
                required: true,
            }
        },
        highlight: function(element) {
            $(element).closest('.form-group').addClass('has-error');
        },
        unhighlight: function(element) {
            $(element).closest('.form-group').removeClass('has-error');
        },
        errorElement: 'span',
        errorClass: 'help-block',
        errorPlacement: function(error, element) {
            if (element.parent('.input-group').length) {
                error.insertAfter(element.parent());
            } else {
                error.insertAfter(element);
            }
        },

        //Monta a mensagem em uma caixa separada se necessário
        //errorLabelContainer: $('#mensagens'),

        //função para enviar após a validação
        submitHandler: function(form) {
           GravaUpload(event);
        } //end-submiteHandler  
    });
});

Shipping Form:

<form class="well" id="frmUpload" action="" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="fileUpload">Selecione o Documento para Upload</label>
        <input type="file" name="fileUpload">
    </div>
    <input type="submit" class="btn btn-primary" value="Upload">
</form> 

Upload Process:

// Ativar relatórios de erro php
error_reporting(E_ALL);
ini_set('display_errors', 1);


if ($_SERVER['REQUEST_METHOD'] == 'POST') { 

    $name     = $_FILES['fileUpload']['name'];
    $tmpName  = $_FILES['fileUpload']['tmp_name'];
    $error    = $_FILES['fileUpload']['error'];
    $size     = $_FILES['fileUpload']['size'];
    $ext      = strtolower(pathinfo($name, PATHINFO_EXTENSION));

    switch ($error) {
        case UPLOAD_ERR_OK:
            $valid = true;
            //validate file extensions
            if ( !in_array($ext, array('jpg','jpeg','png','gif','doc','docx','pdf','xls')) ) {
                $valid = false;
                $aretorno["msg"] = 'Extensao de arquivo invalida ';
            }
            //validate file size
            if ( $size/1024/1024 > 2 ) {
                $valid = false;
                $aretorno["msg"] = 'Tamanho do arquivo e superior a tamanho maximo permitido';
            }
            //upload file
            if ($valid) {
                $targetPath =  dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'arquivos' . DIRECTORY_SEPARATOR. $name;
                move_uploaded_file($tmpName,$targetPath); 
                header( 'Location: DetalhesContrato.php' ) ;
                exit;
            }
            break;
        case UPLOAD_ERR_INI_SIZE:
            $aretorno["msg"] = 'O arquivo enviado excede a directiva upload_max_filesize em php.ini.';
            break;
        case UPLOAD_ERR_PARTIAL:
            $aretorno["msg"] = 'O arquivo foi apenas parcialmente enviado.';
            break;
        case UPLOAD_ERR_NO_FILE:
            $aretorno["msg"] = 'Nenhum arquivo foi transferido.';
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $aretorno["msg"] = 'Faltando uma pasta temporaria. Introduzida no PHP 4.3.10 e PHP 5.0.3.';
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $aretorno["msg"] = 'Falha ao gravar arquivo em disco. Introduzido no PHP 5.1.0.';
            break;
        default:
            $aretorno["msg"] = 'Erro desconhecido';
        break;
    }

    // echo $response;


    //retornando o status / mensagem da execução
    header('Content-Type: application/json');
    echo json_encode($aretorno);    

}

Upload falls on first exception:

var msg = '<div class="alert alert-danger" role="alert">Ocorreu um erro ao tentar manipular os dados. Verifique sua conexão com o banco de dados.</div>';

I’m still not using connection with BD because I’m not sending anything.

  • Sending a file with ajax?

  • 2
  • Go to your browser console, and check the error in the network tab. It gets easier

  • Send file with ajax ? if you are trying to send an image should use the toDataURL() because ajax only sends text data.

1 answer

6


It always falls into the first exception because it is not a problem with the database but with the try/catch.

Solving the problem at the front-end

try {
    var json = $.parseJSON(jqXHR.responseText);
    var msg = '' + json.errorMessage + '.';
    $("#resultado-upload").html(msg);
} catch(e) { 
    var msg = 'Ocorreu um erro ao tentar manipular os dados. Verifique sua conexão com o banco de dados.';
    $("#resultado-upload").html(msg);
}

In the catch you should report the error of parseJSON, but instead you created a front-end error that does not match the jqXHR.responseText, ie it is a fault of its logic. The correct one was to present the error of the variable e, the use of $.post is also without the done and the $.post does not upload as far as I know, you should use FormData for this reason.

An example as $.ajax and FormData:

function GravaUpload(event) {
    var arquivo = $('#frmUpload input[name=fileUpload]');

    var dados = new FormData;
    dados.append('fileUpload', arquivo[0]);

    $.ajax({
        url: 'file/destination.html', 
        type: 'POST',
        data: dados,
        dataType: "json",//Força o tipo json na resposta
        processData: false
    }).done(function(data) {
        $("#resultado-upload").html(data.msg);
    }).fail(function(jqXHR, textStatus, errorThrown) {
        $("#resultado-upload").html("Erro:" + textStatus);
    });
}

Alternatively you can also use https://github.com/blueimp/jQuery-File-Upload

Solving the problem in the back-end

The other problem is in PHP, where you set this $aretorno["msg"], but the variable $aretorno does not exist, so there must be some error in your php saying something like:

Undefined variable $aretorno

To fix just create the variable of type array, so:

error_reporting(E_ALL);
ini_set('display_errors', 1);

$aretorno = array();//Cria a variavel

if ($_SERVER['REQUEST_METHOD'] == 'POST') { 

    $name     = $_FILES['fileUpload']['name'];
    $tmpName  = $_FILES['fileUpload']['tmp_name'];
    $error    = $_FILES['fileUpload']['error'];
    $size     = $_FILES['fileUpload']['size'];
    $ext      = strtolower(pathinfo($name, PATHINFO_EXTENSION));

    switch ($error) {
        case UPLOAD_ERR_OK:
            $valid = true;
            //validate file extensions
            if ( !in_array($ext, array('jpg','jpeg','png','gif','doc','docx','pdf','xls')) ) {
                $valid = false;
                $aretorno["msg"] = 'Extensao de arquivo invalida ';
            }
            //validate file size
            if ( $size/1024/1024 > 2 ) {
                $valid = false;
                $aretorno["msg"] = 'Tamanho do arquivo e superior a tamanho maximo permitido';
            }
            //upload file
            if ($valid) {
                $targetPath =  dirname( __FILE__ ) . DIRECTORY_SEPARATOR. 'arquivos' . DIRECTORY_SEPARATOR. $name;
                move_uploaded_file($tmpName,$targetPath); 
                header( 'Location: DetalhesContrato.php' ) ;
                exit;
            }
            break;
        case UPLOAD_ERR_INI_SIZE:
            $aretorno["msg"] = 'O arquivo enviado excede a directiva upload_max_filesize em php.ini.';
            break;
        case UPLOAD_ERR_PARTIAL:
            $aretorno["msg"] = 'O arquivo foi apenas parcialmente enviado.';
            break;
        case UPLOAD_ERR_NO_FILE:
            $aretorno["msg"] = 'Nenhum arquivo foi transferido.';
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $aretorno["msg"] = 'Faltando uma pasta temporaria. Introduzida no PHP 4.3.10 e PHP 5.0.3.';
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $aretorno["msg"] = 'Falha ao gravar arquivo em disco. Introduzido no PHP 5.1.0.';
            break;
        default:
            $aretorno["msg"] = 'Erro desconhecido';
        break;
    }
} else {
    //Envia um erro acaso o usuário tente acessar o script por outros métodos
    $aretorno["msg"] = 'Método HTTP não suportado para está ação';
}

header('Content-Type: application/json');
echo json_encode($aretorno);

Extras

Note that the pathinfo only takes the extension and many times the extension may not represent the actual content of the file, since the extension can be changed, this is very IMPORTANT, because if you want assurance that the file type sent is what you want then you will have to use another method, I answered a question about this and it can help you, see:

Just change the variable to:

$permitidos = array(
    'jpg','jpeg','png','gif','doc','docx','pdf','xls'
);

and use the variable $tmpName to catch the mimetype.

$permitidos = array(
    'jpg','jpeg','png','gif','doc','docx','pdf','xls'
);

$infos = mimeType($tmpName);

//Transforma image/jpeg em jpeg por exemplo
$infos = preg_replace('#^[a-zA-Z\-]+\/#', '', $infos);

$infos = str_replace('x-', '', $infos);

if (false === in_array($infos, $permitidos)) {
    $aretorno["msg"] = 'O tipo de arquivo enviado é inválido, permitido somente imagens';
}
  • 2

    Fantastic, thank you so much @Guilherme Nascimento, the explanation is complete.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.