Upload only with jQuery.ajax and PHP

2

I would like to know if you can upload a file using only $.ajax({...}) without submitting submit of the form and if, like?

Note: I would like to put this script in the onchange event. Obs2 .: If possible I do not want to send the whole form, just the file along with an association code.

Example:

$(this).on('change', '#image-file', function(event) {
   event.preventDefault();
   if ($(this).val() != ''){
      $.ajax({
         url: '<?=SITE_URL?>upload',
         type: 'POST',
         data: {file: $(this).val(), codigo: '123'},
         success: function(data){/*callback de sucesso*/}
      });

   }
});

You would only submit the form when saving other data. The input of the file is inside the form, and I would like not to need to get it inside and create another one.

Edited

How to send and receive this data with PHP?

    
asked by anonymous 03.12.2014 / 21:55

1 answer

2

It is possible, yes, using the HTML5 File API you can do it here;

NOTE: Example with progress bar right

var percentageSent = 0;
$.ajax({
    type: 'PUT', //ou POST se for seu caso
    crossDomain: true, //true ou false, depende da sua necessidade
    url: 'http://exemplo.com/',
    processData: false,
    headers: {
        'x-foo': 'bar', //só se voce precisar
    },
    data: seuArquivo, //Veja a explicação abaixo
    xhr: function() {
        myXhr = $.ajaxSettings.xhr();

        if(myXhr.upload){
            myXhr.upload.addEventListener('progress', function(e) {
                if(e.lengthComputable) {
                    var percentageSent = (e.loaded / seuArquivo.size);

                    $('#progress').html(percentageSent * 100 + '%');
                }
            }, false);

            myXhr.upload.addEventListener('load', function(e) {
                //Terminou de enviar esta parte
            }, false);
        }

        return myXhr;
    },
}).done(function(data, textStatus, jqXHR) {
    var etag = jqXHR.getResponseHeader('etag'); //caso voce precisa da etag
}).fail(function() {
    //algo deu errado
});

The variable seuArquivo of the above example you can get with the HTML5 File API, it is a BLOB, here at MDN documentation has several examples!

Basically you get this blob like this;

document.getElementById("uploadInput").files

Or in your case;

...
data: $(this).get(0).files[0]
...

Update (Receiving additional files and data)

You can receive the file by PUT method, as per the PHP documentation:

<?php
/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");

/* Abre o arquivo para escrita (No caso cria ele, e escreve o que está sendo recebido) */
$fp = fopen("myputfile.ext", "w");

/* Lê 1kb de dados por vez
   e escreve no arquivo */
while ($data = fread($putdata, 1024))
  fwrite($fp, $data);

/* Fecha os streams */
fclose($fp);
fclose($putdata);
?>

To send information about the file and other data, send it by header in ajax statement:

headers: {
   'file-type': seuArquivo.type, //só se voce precisar
   'file-name': seuArquivo.name,
   'file-size': seuArquivo.size,
   'info-adicional' : 'Foobar'
}

And get it like this in PHP:

$headers = getallheaders();
// $headers['file-type']
// $headers['file-name']
// $headers['file-size']
// $headers['info-adicional']
    
03.12.2014 / 22:05