Upload de arquivo jQuery Ajax

755

Posso usar o seguinte código jQuery para executar o upload de arquivo usando o método POST de uma solicitação ajax?

$.ajax({
    type: "POST",
    timeout: 50000,
    url: url,
    data: dataString,
    success: function (data) {
        alert('success');
        return false;
    }
});

Se for possível, preciso preencher uma datapeça? É o caminho correto? Eu apenas POSTAR o arquivo para o lado do servidor.

Tenho pesquisado no Google, mas o que encontrei foi um plug-in, enquanto no meu plano não quero usá-lo. Pelo menos por enquanto.

Willy
fonte
O Ajax não suporta o upload de arquivos, você deve usar iframe vez
antyrat
1
Pergunta relacionada: stackoverflow.com/questions/6974684/…
Nathan Koop
2
Veja também: stackoverflow.com/questions/166221/…
Timo Huovinen

Respostas:

596

O upload de arquivo não é possível através do AJAX.
Você pode fazer upload de arquivo, sem atualizar a página usando IFrame.
Você pode conferir mais detalhes aqui .


ATUALIZAR

Com o XHR2, o upload de arquivos através do AJAX é suportado. Por exemplo, através do FormDataobjeto, mas infelizmente não é suportado por todos os navegadores antigos /.

FormData o suporte começa nas seguintes versões dos navegadores de desktop.

  • IE 10+
  • Firefox 4.0 ou superior
  • Chrome 7 ou superior
  • Safari 5+
  • Opera 12+

Para mais detalhes, consulte o link MDN .

Adeel
fonte
41
Aqui está uma lista dos navegadores específicos que não são suportados: caniuse.com/#search=FormData Também eu não testei isso, mas aqui é um polyfill para FormData gist.github.com/3120320
Ryan White
152
Especificamente, o IE <10 não, para aqueles com preguiça de ler o link.
Kevin
22
@Synexis não, não precisamos esperar tanto tempo, porque todo o IE possui apenas 22% do mercado mundial e 27% nos EUA, caindo rapidamente. As chances são de pessoas com mais de 70 anos de idade. Então, em vez de o IE ditar o que os desenvolvedores devem fazer, o IE terá que se moldar ou sair da corrida.
Tirou Calder
30
@DrewCalder A maioria dos usuários do IE são trabalhadores de escritório que não têm a escolha de qual navegador usar devido às políticas da empresa. Não acho que a idade tenha muito a ver com isso. Eu estou supondo que a maioria das pessoas> 70 obter a sua prole para instalar o Chrome ou FF em vez :)
Nicolas Connault
3
Esse link realmente me ajudou a entender o mínimo. Não precisei usar uma solicitação xhr. Se você usa o ajax, defina enctypecomo "form/multipart"!
Luminous
316

O Iframes não é mais necessário para fazer upload de arquivos através do ajax. Eu fiz recentemente isso sozinho. Confira estas páginas:

Usando uploads de arquivos HTML5 com AJAX e jQuery

http://dev.w3.org/2006/webapi/FileAPI/#FileReader-interface

Atualizou a resposta e a limpou. Use a função getSize para verificar o tamanho ou use a função getType para verificar os tipos. Adicionado progressbar html e código css.

var Upload = function (file) {
    this.file = file;
};

Upload.prototype.getType = function() {
    return this.file.type;
};
Upload.prototype.getSize = function() {
    return this.file.size;
};
Upload.prototype.getName = function() {
    return this.file.name;
};
Upload.prototype.doUpload = function () {
    var that = this;
    var formData = new FormData();

    // add assoc key values, this will be posts values
    formData.append("file", this.file, this.getName());
    formData.append("upload_file", true);

    $.ajax({
        type: "POST",
        url: "script",
        xhr: function () {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                myXhr.upload.addEventListener('progress', that.progressHandling, false);
            }
            return myXhr;
        },
        success: function (data) {
            // your callback here
        },
        error: function (error) {
            // handle error
        },
        async: true,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        timeout: 60000
    });
};

Upload.prototype.progressHandling = function (event) {
    var percent = 0;
    var position = event.loaded || event.position;
    var total = event.total;
    var progress_bar_id = "#progress-wrp";
    if (event.lengthComputable) {
        percent = Math.ceil(position / total * 100);
    }
    // update progressbars classes so it fits your code
    $(progress_bar_id + " .progress-bar").css("width", +percent + "%");
    $(progress_bar_id + " .status").text(percent + "%");
};

Como usar a classe Upload

//Change id to your id
$("#ingredient_file").on("change", function (e) {
    var file = $(this)[0].files[0];
    var upload = new Upload(file);

    // maby check size or type here with upload.getSize() and upload.getType()

    // execute upload
    upload.doUpload();
});

Código html Progressbar

<div id="progress-wrp">
    <div class="progress-bar"></div>
    <div class="status">0%</div>
</div>

Código CSS Progressbar

#progress-wrp {
  border: 1px solid #0099CC;
  padding: 1px;
  position: relative;
  height: 30px;
  border-radius: 3px;
  margin: 10px;
  text-align: left;
  background: #fff;
  box-shadow: inset 1px 3px 6px rgba(0, 0, 0, 0.12);
}

#progress-wrp .progress-bar {
  height: 100%;
  border-radius: 3px;
  background-color: #f39ac7;
  width: 0;
  box-shadow: inset 1px 1px 10px rgba(0, 0, 0, 0.11);
}

#progress-wrp .status {
  top: 3px;
  left: 50%;
  position: absolute;
  display: inline-block;
  color: #000000;
}
Ziinloader
fonte
3
Você pode copiar mais ou menos o código imediatamente e usá-lo. Basta alterar alguns nomes de identificação e nomes de classe. Qualquer consumação é por sua conta.
Ziinloader
4
Observe que o myXhr parece ser global, além de nome, tamanho e tipo. Também é melhor usar "beforeSend" para aumentar o objeto XMLHttpRequest já criado, em vez de usar "xhr" para criar um e depois alterá-lo.
awatts
8
Acho que não podemos usar isso como é o @Ziinloader. Você está usando algum método local que não está incluído: writer(catchFile). O que é writer()?
Tandrewnichols
4
E se os dados também contiverem alguns campos junto com o arquivo a ser carregado?
Raju
2
@Ziinloader Este é um exemplo tremendamente útil que vejo que você voltou e manteve várias vezes. Verdadeiramente uma resposta vale muito mais do que aquela que posso dar.
Regular Joe
191

O arquivo Ajax de publicação e upload é possível. Estou usando a jQuery $.ajaxfunção para carregar meus arquivos. Tentei usar o objeto XHR, mas não consegui obter resultados no lado do servidor com o PHP.

var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);

$.ajax({
       url : 'upload.php',
       type : 'POST',
       data : formData,
       processData: false,  // tell jQuery not to process the data
       contentType: false,  // tell jQuery not to set contentType
       success : function(data) {
           console.log(data);
           alert(data);
       }
});

Como você pode ver, você deve criar um objeto FormData, vazio ou de (serializado? - $('#yourForm').serialize())formulário existente e, em seguida, anexar o arquivo de entrada.

Aqui estão mais informações: - Como fazer upload de um arquivo usando jQuery.ajax e FormData - Como fazer upload de arquivos via jQuery, o objeto FormData é fornecido e nenhum nome de arquivo, solicitação GET

Para o processo PHP, você pode usar algo como isto:

//print_r($_FILES);
$fileName = $_FILES['file']['name'];
$fileType = $_FILES['file']['type'];
$fileError = $_FILES['file']['error'];
$fileContent = file_get_contents($_FILES['file']['tmp_name']);

if($fileError == UPLOAD_ERR_OK){
   //Processes your file here
}else{
   switch($fileError){
     case UPLOAD_ERR_INI_SIZE:   
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_FORM_SIZE:  
          $message = 'Error al intentar subir un archivo que excede el tamaño permitido.';
          break;
     case UPLOAD_ERR_PARTIAL:    
          $message = 'Error: no terminó la acción de subir el archivo.';
          break;
     case UPLOAD_ERR_NO_FILE:    
          $message = 'Error: ningún archivo fue subido.';
          break;
     case UPLOAD_ERR_NO_TMP_DIR: 
          $message = 'Error: servidor no configurado para carga de archivos.';
          break;
     case UPLOAD_ERR_CANT_WRITE: 
          $message= 'Error: posible falla al grabar el archivo.';
          break;
     case  UPLOAD_ERR_EXTENSION: 
          $message = 'Error: carga de archivo no completada.';
          break;
     default: $message = 'Error: carga de archivo no completada.';
              break;
    }
      echo json_encode(array(
               'error' => true,
               'message' => $message
            ));
}
pedrozopayares
fonte
2
Qual biblioteca jquery eu preciso fazer referência para executar este código?
Rayden Black
A resposta foi escrita em 2014. A versão do JQuery era 1.10. Eu não tentei com versões mais recentes.
pedrozopayares
5
formData.append('file', $('#file')[0].files[0]);retorna undefinede console.log(formData) não tem nada, exceto_proto_
Yakob Ubaidi
1
Não é suportado pelo IE 9, caso alguns estejam presos no mesmo inferno que eu
#
3
Eu consegui que isso funcionasse ... Belisque-me, estou no paraíso de upload de arquivos jQuery Ajax! var formData = new FormData(); formData.append('file', document.getElementById('file').files[0]); $.ajax({ url : $("form[name='uploadPhoto']").attr("action"), type : 'POST', data : formData, processData: false, // tell jQuery not to process the data contentType: false, // tell jQuery not to set contentType success : function(data) { console.log(data); alert(data); } });
TARKUS 30/01
104

Formulário de Upload Simples

 <script>
   //form Submit
   $("form").submit(function(evt){	 
      evt.preventDefault();
      var formData = new FormData($(this)[0]);
   $.ajax({
       url: 'fileUpload',
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
 });
</script>
<!--Upload Form-->
<form>
  <table>
    <tr>
      <td colspan="2">File Upload</td>
    </tr>
    <tr>
      <th>Select File </th>
      <td><input id="csv" name="csv" type="file" /></td>
    </tr>
    <tr>
      <td colspan="2">
        <input type="submit" value="submit"/> 
      </td>
    </tr>
  </table>
</form>

vickisys
fonte
senhor quais são os js que foram usados ​​neste exemplo, existe um plugin jquery específico para este .. tenho uma pergunta que fui apontada aqui, por favor, verifique minha pergunta .. quero fazer upload de vários arquivos ou imagens nesse projeto aqui é o link stackoverflow.com/questions/28644200/…
Brownman Revival 24/02
19
$ (this) [0] is this
machineaddict
2
Qual é o parâmetro no servidor para o arquivo postado? Você pode postar parte do servidor.
FrenkyB
@FrenkyB e outros - os arquivos no servidor (em PHP) não são armazenados na variável $ _POST - eles são armazenados na variável $ _FILES. Nesse caso, você o acessaria com $ _FILES ["csv"] porque "csv" é o atributo de nome da tag de entrada.
precisa saber é o seguinte
68

Estou muito atrasado para isso, mas estava procurando uma solução de upload de imagens baseada em ajax e a resposta que procurava estava meio dispersa por todo este post. A solução em que decidi envolvia o objeto FormData. Montei uma forma básica do código que montei. Você pode ver que ele demonstra como adicionar um campo personalizado ao formulário com fd.append () e também como manipular dados de resposta quando a solicitação ajax é concluída.

Carregar html:

<!DOCTYPE html>
<html>
<head>
    <title>Image Upload Form</title>
    <script src="//code.jquery.com/jquery-1.9.1.js"></script>
    <script type="text/javascript">
        function submitForm() {
            console.log("submit event");
            var fd = new FormData(document.getElementById("fileinfo"));
            fd.append("label", "WEBUPLOAD");
            $.ajax({
              url: "upload.php",
              type: "POST",
              data: fd,
              processData: false,  // tell jQuery not to process the data
              contentType: false   // tell jQuery not to set contentType
            }).done(function( data ) {
                console.log("PHP Output:");
                console.log( data );
            });
            return false;
        }
    </script>
</head>

<body>
    <form method="post" id="fileinfo" name="fileinfo" onsubmit="return submitForm();">
        <label>Select a file:</label><br>
        <input type="file" name="file" required />
        <input type="submit" value="Upload" />
    </form>
    <div id="output"></div>
</body>
</html>

Caso você esteja trabalhando com o php, aqui está uma maneira de lidar com o upload, que inclui o uso dos dois campos personalizados demonstrados no html acima.

Upload.php

<?php
if ($_POST["label"]) {
    $label = $_POST["label"];
}
$allowedExts = array("gif", "jpeg", "jpg", "png");
$temp = explode(".", $_FILES["file"]["name"]);
$extension = end($temp);
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 200000)
&& in_array($extension, $allowedExts)) {
    if ($_FILES["file"]["error"] > 0) {
        echo "Return Code: " . $_FILES["file"]["error"] . "<br>";
    } else {
        $filename = $label.$_FILES["file"]["name"];
        echo "Upload: " . $_FILES["file"]["name"] . "<br>";
        echo "Type: " . $_FILES["file"]["type"] . "<br>";
        echo "Size: " . ($_FILES["file"]["size"] / 1024) . " kB<br>";
        echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";

        if (file_exists("uploads/" . $filename)) {
            echo $filename . " already exists. ";
        } else {
            move_uploaded_file($_FILES["file"]["tmp_name"],
            "uploads/" . $filename);
            echo "Stored in: " . "uploads/" . $filename;
        }
    }
} else {
    echo "Invalid file";
}
?>
lee8oi
fonte
Estou recebendo Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https,Por isso é tão sir i copiar e colar o código como está
Brownman Revival
2
@HogRider - se você pesquisar sua mensagem de erro no Google, este é o primeiro resultado: stackoverflow.com/questions/10752055/… Você está acessando suas páginas da Web localmente file://, em vez de usar um servidor da Web? Como um aparte, não é uma prática recomendada simplesmente copiar e colar código às cegas sem primeiro entendê-lo. Eu recomendaria que você seguisse o código linha por linha para entender o que está acontecendo antes de colocar o código em uso.
Colincameron 18/03/2015
@colincameron obrigado por esclarecer algumas coisas que eu fiz através da linha por linha e eu realmente não entendo muito, então eu fiz a pergunta para que alguém possa esclarecer minhas dúvidas. Eu estou usando local por xampp maneira de ser exato. Posso fazer uma pergunta que talvez você possa esclarecer?
Brownman Revival
@ Brownown Revival: Eu sei que é tarde demais para a resposta .. Você recebeu um erro de origem cruzada porque abriu o arquivo html como arquivo do que executá-lo no servidor.
Adarsh Mohan
@AdarshMohan, eu agradeço a resposta, como você sugere que eu faça isso para corrigi-lo?
Brownman Revival
31

Um upload de AJAX é realmente possível com XMLHttpRequest(). Não são necessários iframes. O progresso do upload pode ser mostrado.

Para obter detalhes, consulte: Responda https://stackoverflow.com/a/4943774/873282 para questionar o jQuery Upload Progress e o upload de arquivo AJAX .

koppor
fonte
24
Infelizmente, o IE <10 não suporta isso.
Sasha Chedygov
1
Quando você deseja apenas se referir a outra página como resposta, pode votar para fechar como um dupkucate ou deixar um comentário na pergunta. Esta publicação não é uma resposta. Uma postagem desse tipo parece uma tentativa de criar um representante.
Mckmackusa #
18

Aqui está como eu consegui esse trabalho:

HTML

<input type="file" id="file">
<button id='process-file-button'>Process</button>

JS

$('#process-file-button').on('click', function (e) {
    let files = new FormData(), // you can consider this as 'data bag'
        url = 'yourUrl';

    files.append('fileName', $('#file')[0].files[0]); // append selected file to the bag named 'file'

    $.ajax({
        type: 'post',
        url: url,
        processData: false,
        contentType: false,
        data: files,
        success: function (response) {
            console.log(response);
        },
        error: function (err) {
            console.log(err);
        }
    });
});

PHP

if (isset($_FILES) && !empty($_FILES)) {
    $file = $_FILES['fileName'];
    $name = $file['name'];
    $path = $file['tmp_name'];


    // process your file

}
М.Б.
fonte
2
O que ajudou a mais para mim sobre isso foi o $('#file')[0].files[0]que é algum tipo de JS estranhos resolver sem a necessidade de uma adequada<form>
ffgpga08
Esta é a solução completa, o bit PHP também ajuda.
Cdsaenz
14

Caso você queira fazer assim:

$.upload( form.action, new FormData( myForm))
.progress( function( progressEvent, upload) {
    if( progressEvent.lengthComputable) {
        var percent = Math.round( progressEvent.loaded * 100 / progressEvent.total) + '%';
        if( upload) {
            console.log( percent + ' uploaded');
        } else {
            console.log( percent + ' downloaded');
        }
    }
})
.done( function() {
    console.log( 'Finished upload');                    
});

do que

https://github.com/lgersman/jquery.orangevolt-ampere/blob/master/src/jquery.upload.js

pode ser sua solução.

lgersman
fonte
Onde está o método de upload no objeto $, o link acima não existe
legal é
2
Obrigado por postar sua resposta! Leia atentamente as Perguntas frequentes sobre autopromoção. Observe também que é necessário que você publique um aviso sempre que vincular ao seu próprio site / produto.
Andrew Barber
13
  • Use um iframe oculto e defina o destino do seu formulário com o nome desse iframe. Dessa forma, quando o formulário for enviado, apenas o iframe será atualizado.
  • Tenha um manipulador de eventos registrado para o evento de carregamento do iframe para analisar a resposta.

Mais detalhes no meu blog: http://blog.manki.in/2011/08/ajax-fie-upload.html .

Manki
fonte
Evite iframe sempre que possível
Bhargav Nanekalva
@BhargavNanekalva, qual é a sua preocupação?
aswzen
13
$("#submit_car").click( function() {
  var formData = new FormData($('#car_cost_form')[0]);
$.ajax({
       url: 'car_costs.php',
       data: formData,
       async: false,
       contentType: false,
       processData: false,
       cache: false,
       type: 'POST',
       success: function(data)
       {
       },
     })    return false;    
});

editar: anote o tipo de conteúdo e processe os dados Você pode simplesmente usá-lo para fazer upload de arquivos via Ajax ...... a entrada de envio não pode estar fora do elemento do formulário :)

Gvice
fonte
3
Usando esse método, você pode postar formulário, mas não com os campos do tipo 'arquivo'. Esta pergunta é especificamente sobre o upload de arquivos.
precisa
11

Atualização de 2019:

html

<form class="fr" method='POST' enctype="multipart/form-data"> {% csrf_token %}
<textarea name='text'>
<input name='example_image'>
<button type="submit">
</form>

js

$(document).on('submit', '.fr', function(){

    $.ajax({ 
        type: 'post', 
        url: url, <--- you insert proper URL path to call your views.py function here.
        enctype: 'multipart/form-data',
        processData: false,
        contentType: false,
        data: new FormData(this) ,
        success: function(data) {
             console.log(data);
        }
        });
        return false;

    });

views.py

form = ThisForm(request.POST, request.FILES)

if form.is_valid():
    text = form.cleaned_data.get("text")
    example_image = request.FILES['example_image']
Jay
fonte
1
Como isso melhora alguma das respostas já dadas? Além disso, esta resposta menciona um arquivo views.py que é o Django e não tem nada a ver com a pergunta.
dirkgroten 13/03/19
6
Como o problema se manifesta comparativamente ao usar o Django, e se você estiver usando o Django, não há muita direção aqui em relação a resolvê-lo. Pensei em oferecer assistência proativa caso alguém chegasse aqui, como eu fiz no futuro. Tendo um dia difícil?
Jay
9

Use FormData. Funciona muito bem :-) ...

var jform = new FormData();
jform.append('user',$('#user').val());
jform.append('image',$('#image').get(0).files[0]); // Here's the important bit

$.ajax({
    url: '/your-form-processing-page-url-here',
    type: 'POST',
    data: jform,
    dataType: 'json',
    mimeType: 'multipart/form-data', // this too
    contentType: false,
    cache: false,
    processData: false,
    success: function(data, status, jqXHR){
        alert('Hooray! All is well.');
        console.log(data);
        console.log(status);
        console.log(jqXHR);

    },
    error: function(jqXHR,status,error){
        // Hopefully we should never reach here
        console.log(jqXHR);
        console.log(status);
        console.log(error);
    }
});
delboy1978uk
fonte
é isso que: ('usuário', $ ('# usuário'). val ());
rahim.nagori 26/03
caixa de texto com id = "usuário" é anexada ao formulário @ rahim.nagori
Alp Altunel
1
Uma abordagem mais direta: var jform = new FormData ($ ('form'). Get (0));
André Morales
bom, obrigado, vou tentar que da próxima vez eu uso FormData
delboy1978uk
7

Eu implementei uma seleção de vários arquivos com visualização instantânea e upload após remover arquivos indesejados da visualização via ajax.

Documentação detalhada pode ser encontrada aqui: http://anasthecoder.blogspot.ae/2014/12/multi-file-select-preview-without.html

Demonstração: http://jsfiddle.net/anas/6v8Kz/7/embedded/result/

jsFiddle: http://jsfiddle.net/anas/6v8Kz/7/

Javascript:

    $(document).ready(function(){
    $('form').submit(function(ev){
        $('.overlay').show();
        $(window).scrollTop(0);
        return upload_images_selected(ev, ev.target);
    })
})
function add_new_file_uploader(addBtn) {
    var currentRow = $(addBtn).parent().parent();
    var newRow = $(currentRow).clone();
    $(newRow).find('.previewImage, .imagePreviewTable').hide();
    $(newRow).find('.removeButton').show();
    $(newRow).find('table.imagePreviewTable').find('tr').remove();
    $(newRow).find('input.multipleImageFileInput').val('');
    $(addBtn).parent().parent().parent().append(newRow);
}

function remove_file_uploader(removeBtn) {
    $(removeBtn).parent().parent().remove();
}

function show_image_preview(file_selector) {
    //files selected using current file selector
    var files = file_selector.files;
    //Container of image previews
    var imageContainer = $(file_selector).next('table.imagePreviewTable');
    //Number of images selected
    var number_of_images = files.length;
    //Build image preview row
    var imagePreviewRow = $('<tr class="imagePreviewRow_0"><td valign=top style="width: 510px;"></td>' +
        '<td valign=top><input type="button" value="X" title="Remove Image" class="removeImageButton" imageIndex="0" onclick="remove_selected_image(this)" /></td>' +
        '</tr> ');
    //Add image preview row
    $(imageContainer).html(imagePreviewRow);
    if (number_of_images > 1) {
        for (var i =1; i<number_of_images; i++) {
            /**
             *Generate class name of the respective image container appending index of selected images, 
             *sothat we can match images selected and the one which is previewed
             */
            var newImagePreviewRow = $(imagePreviewRow).clone().removeClass('imagePreviewRow_0').addClass('imagePreviewRow_'+i);
            $(newImagePreviewRow).find('input[type="button"]').attr('imageIndex', i);
            $(imageContainer).append(newImagePreviewRow);
        }
    }
    for (var i = 0; i < files.length; i++) {
        var file = files[i];
        /**
         * Allow only images
         */
        var imageType = /image.*/;
        if (!file.type.match(imageType)) {
          continue;
        }

        /**
         * Create an image dom object dynamically
         */
        var img = document.createElement("img");

        /**
         * Get preview area of the image
         */
        var preview = $(imageContainer).find('tr.imagePreviewRow_'+i).find('td:first');

        /**
         * Append preview of selected image to the corresponding container
         */
        preview.append(img); 

        /**
         * Set style of appended preview(Can be done via css also)
         */
        preview.find('img').addClass('previewImage').css({'max-width': '500px', 'max-height': '500px'});

        /**
         * Initialize file reader
         */
        var reader = new FileReader();
        /**
         * Onload event of file reader assign target image to the preview
         */
        reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
        /**
         * Initiate read
         */
        reader.readAsDataURL(file);
    }
    /**
     * Show preview
     */
    $(imageContainer).show();
}

function remove_selected_image(close_button)
{
    /**
     * Remove this image from preview
     */
    var imageIndex = $(close_button).attr('imageindex');
    $(close_button).parents('.imagePreviewRow_' + imageIndex).remove();
}

function upload_images_selected(event, formObj)
{
    event.preventDefault();
    //Get number of images
    var imageCount = $('.previewImage').length;
    //Get all multi select inputs
    var fileInputs = document.querySelectorAll('.multipleImageFileInput');
    //Url where the image is to be uploaded
    var url= "/upload-directory/";
    //Get number of inputs
    var number_of_inputs = $(fileInputs).length; 
    var inputCount = 0;

    //Iterate through each file selector input
    $(fileInputs).each(function(index, input){

        fileList = input.files;
        // Create a new FormData object.
        var formData = new FormData();
        //Extra parameters can be added to the form data object
        formData.append('bulk_upload', '1');
        formData.append('username', $('input[name="username"]').val());
        //Iterate throug each images selected by each file selector and find if the image is present in the preview
        for (var i = 0; i < fileList.length; i++) {
            if ($(input).next('.imagePreviewTable').find('.imagePreviewRow_'+i).length != 0) {
                var file = fileList[i];
                // Check the file type.
                if (!file.type.match('image.*')) {
                    continue;
                }
                // Add the file to the request.
                formData.append('image_uploader_multiple[' +(inputCount++)+ ']', file, file.name);
            }
        }
        // Set up the request.
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.onload = function () {
            if (xhr.status === 200) {
                var jsonResponse = JSON.parse(xhr.responseText);
                if (jsonResponse.status == 1) {
                    $(jsonResponse.file_info).each(function(){
                        //Iterate through response and find data corresponding to each file uploaded
                        var uploaded_file_name = this.original;
                        var saved_file_name = this.target;
                        var file_name_input = '<input type="hidden" class="image_name" name="image_names[]" value="' +saved_file_name+ '" />';
                        file_info_container.append(file_name_input);

                        imageCount--;
                    })
                    //Decrement count of inputs to find all images selected by all multi select are uploaded
                    number_of_inputs--;
                    if(number_of_inputs == 0) {
                        //All images selected by each file selector is uploaded
                        //Do necessary acteion post upload
                        $('.overlay').hide();
                    }
                } else {
                    if (typeof jsonResponse.error_field_name != 'undefined') {
                        //Do appropriate error action
                    } else {
                        alert(jsonResponse.message);
                    }
                    $('.overlay').hide();
                    event.preventDefault();
                    return false;
                }
            } else {
                /*alert('Something went wrong!');*/
                $('.overlay').hide();
                event.preventDefault();
            }
        };
        xhr.send(formData);
    })

    return false;
}
Eu sou um
fonte
@Bhargav: Por favor, consulte a publicação no blog para obter explicações: goo.gl/umgFFy . Se você ainda tiver alguma dúvida, volte para mim Obrigado
Ima
7

Eu lidei com isso em um código simples. Você pode baixar uma demonstração de trabalho aqui

Para o seu caso, isso é muito possível. Vou mostrar passo a passo como você pode enviar um arquivo para o servidor usando o AJAX jquery.

Primeiro, vamos criar um arquivo HTML para adicionar o seguinte elemento de arquivo de formulário, como mostrado abaixo.

<form action="" id="formContent" method="post" enctype="multipart/form-data" >
         <input  type="file" name="file"  required id="upload">
         <button class="submitI" >Upload Image</button> 
</form>

Em segundo lugar, crie um arquivo jquery.js e adicione o seguinte código para lidar com o envio de arquivos ao servidor

    $("#formContent").submit(function(e){
        e.preventDefault();

    var formdata = new FormData(this);

        $.ajax({
            url: "ajax_upload_image.php",
            type: "POST",
            data: formdata,
            mimeTypes:"multipart/form-data",
            contentType: false,
            cache: false,
            processData: false,
            success: function(){
                alert("file successfully submitted");
            },error: function(){
                alert("okey");
            }
         });
      });
    });

Lá está você pronto. Veja mais

Daniel Nyamasyo
fonte
7

Usar o FormData é o caminho a seguir, conforme indicado por muitas respostas. aqui está um pouco de código que funciona muito bem para esse fim. Também concordo com o comentário de aninhar blocos ajax para concluir circunstâncias complexas. Ao incluir e.PreventDefault (); na minha experiência, torna o código mais compatível com vários navegadores.

    $('#UploadB1').click(function(e){        
    e.preventDefault();

    if (!fileupload.valid()) {
        return false;            
    }

    var myformData = new FormData();        
    myformData.append('file', $('#uploadFile')[0].files[0]);

    $("#UpdateMessage5").html("Uploading file ....");
    $("#UpdateMessage5").css("background","url(../include/images/loaderIcon.gif) no-repeat right");

    myformData.append('mode', 'fileUpload');
    myformData.append('myid', $('#myid').val());
    myformData.append('type', $('#fileType').val());
    //formData.append('myfile', file, file.name); 

    $.ajax({
        url: 'include/fetch.php',
        method: 'post',
        processData: false,
        contentType: false,
        cache: false,
        data: myformData,
        enctype: 'multipart/form-data',
        success: function(response){
            $("#UpdateMessage5").html(response); //.delay(2000).hide(1); 
            $("#UpdateMessage5").css("background","");

            console.log("file successfully submitted");
        },error: function(){
            console.log("not okay");
        }
    });
});
Mike Volmar
fonte
isso executa o formulário através da validação jquery ... if (! fileupload.valid ()) {return false; }
Mike Volmar
7

Usando js puro, é mais fácil

async function saveFile(inp) 
{
    let formData = new FormData();           
    formData.append("file", inp.files[0]);
    await fetch('/upload/somedata', {method: "POST", body: formData});    
    alert('success');
}
<input type="file" onchange="saveFile(this)" >

  • No lado do servidor, você pode ler o nome do arquivo original (e outras informações), que é incluído automaticamente para solicitação.
  • Você NÃO precisa definir o cabeçalho "Content-Type" para "multipart / form-data"; o navegador o definirá automaticamente
  • Essas soluções devem funcionar em todos os principais navegadores.

Aqui está um trecho mais desenvolvido com tratamento de erros e envio de json adicional

Kamil Kiełczewski
fonte
6

Sim, você pode, basta usar javascript para obter o arquivo, certificando-se de ler o arquivo como um URL de dados. Analise as coisas antes da base64 para obter os dados codificados da base 64 e, se você estiver usando php ou qualquer outro idioma de back-end, poderá decodificar os dados da base 64 e salvar em um arquivo como mostrado abaixo

Javascript:
var reader = new FileReader();
reader.onloadend = function ()
{
  dataToBeSent = reader.result.split("base64,")[1];
  $.post(url, {data:dataToBeSent});
}
reader.readAsDataURL(this.files[0]);


PHP:
    file_put_contents('my.pdf', base64_decode($_POST["data"]));

É claro que você provavelmente desejará fazer alguma validação, como verificar com qual tipo de arquivo você está lidando e coisas assim, mas essa é a ideia.

Piacenti
fonte
file_put_contents ($ fname, file_get_contents ($ _ POST ['data'])); file_get_contents lida com a decodificação e os dados: // cabeçalho
Nande 21-21
5
<html>
    <head>
        <title>Ajax file upload</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
        <script>
            $(document).ready(function (e) {
            $("#uploadimage").on('submit', (function(e) {
            e.preventDefault();
                    $.ajax({
                    url: "upload.php", // Url to which the request is send
                            type: "POST", // Type of request to be send, called as method
                            data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
                            contentType: false, // The content type used when sending data to the server.
                            cache: false, // To unable request pages to be cached
                            processData:false, // To send DOMDocument or non processed data file it is set to false
                            success: function(data)   // A function to be called if request succeeds
                            {
                            alert(data);
                            }
                    });
            }));
        </script>
    </head>
    <body>
        <div class="main">
            <h1>Ajax Image Upload</h1><br/>
            <hr>
            <form id="uploadimage" action="" method="post" enctype="multipart/form-data">
                <div id="image_preview"><img id="previewing" src="noimage.png" /></div>
                <hr id="line">
                <div id="selectImage">
                    <label>Select Your Image</label><br/>
                    <input type="file" name="file" id="file" required />
                    <input type="submit" value="Upload" class="submit" />
                </div>
            </form>
        </div>
    </body>
</html>
Nikit Barochiya
fonte
4

Você pode usar o método ajaxSubmit da seguinte forma :) quando você seleciona um arquivo que precisa ser carregado no servidor, o formulário deve ser enviado ao servidor :)

$(document).ready(function () {
    var options = {
    target: '#output',   // target element(s) to be updated with server response
    timeout: 30000,
    error: function (jqXHR, textStatus) {
            $('#output').html('have any error');
            return false;
        }
    },
    success: afterSuccess,  // post-submit callback
    resetForm: true
            // reset the form after successful submit
};

$('#idOfInputFile').on('change', function () {
    $('#idOfForm').ajaxSubmit(options);
    // always return false to prevent standard browser submit and page navigation
    return false;
});
});
Quy Le
fonte
2
Eu acredito que você está falando sobre o plugin de formulário jquery . É realmente a melhor opção aqui, além da falta de detalhes em sua resposta.
Fotanus
@fotanus você está certo! esse script deve usar jquery formulário plugin para enviar método de uso ajaxSubmit que definem em forma plugin jQuery
Quy Le
4

para fazer upload de um arquivo que é enviado pelo usuário como parte do formulário usando jquery, siga o código abaixo:

var formData = new FormData();
formData.append("userfile", fileInputElement.files[0]);

Em seguida, envie o objeto de dados do formulário para o servidor.

Também podemos anexar um Arquivo ou Blob diretamente ao objeto FormData.

data.append("myfile", myBlob, "filename.txt");
VISHNU Radhakrishnan
fonte
3

Se você deseja fazer upload de arquivo usando AJAX, aqui está o código que você pode usar para fazer upload de arquivos.

$(document).ready(function() {
    var options = { 
                beforeSubmit:  showRequest,
        success:       showResponse,
        dataType: 'json' 
        }; 
    $('body').delegate('#image','change', function(){
        $('#upload').ajaxForm(options).submit();        
    }); 
});     
function showRequest(formData, jqForm, options) { 
    $("#validation-errors").hide().empty();
    $("#output").css('display','none');
    return true; 
} 
function showResponse(response, statusText, xhr, $form)  { 
    if(response.success == false)
    {
        var arr = response.errors;
        $.each(arr, function(index, value)
        {
            if (value.length != 0)
            {
                $("#validation-errors").append('<div class="alert alert-error"><strong>'+ value +'</strong><div>');
            }
        });
        $("#validation-errors").show();
    } else {
         $("#output").html("<img src='"+response.file+"' />");
         $("#output").css('display','block');
    }
}

Aqui está o HTML para carregar o arquivo

<form class="form-horizontal" id="upload" enctype="multipart/form-data" method="post" action="upload/image'" autocomplete="off">
    <input type="file" name="image" id="image" /> 
</form>
Nikunj K.
fonte
3

Para obter todas as entradas do seu formulário, incluindo o type = "file", você precisa usar o objeto FormData . você poderá ver o conteúdo do formData no depurador -> rede -> cabeçalhos depois de enviar o formulário.

var url = "YOUR_URL";

var form = $('#YOUR_FORM_ID')[0];
var formData = new FormData(form);


$.ajax(url, {
    method: 'post',
    processData: false,
    contentType: false,
    data: formData
}).done(function(data){
    if (data.success){ 
        alert("Files uploaded");
    } else {
        alert("Error while uploading the files");
    }
}).fail(function(data){
    console.log(data);
    alert("Error while uploading the files");
});
David
fonte
2
var dataform = new FormData($("#myform")[0]);
//console.log(dataform);
$.ajax({
    url: 'url',
    type: 'POST',
    data: dataform,
    async: false,
    success: function(res) {
        response data;
    },
    cache: false,
    contentType: false,
    processData: false
});
Jayesh Paunikar
fonte
5
você pode melhorar sua resposta adicionando alguns detalhes
SR
1

Aqui estava uma idéia que eu estava pensando:

Have an iframe on page and have a referencer.

Tenha um formulário no qual você move o elemento INPUT: File para.

Form:  A processing page AND a target of the FRAME.

O resultado será publicado no quadro e você poderá enviar os dados buscados até um nível para a tag da imagem desejada com algo como:

data:image/png;base64,asdfasdfasdfasdfa

e a página é carregada.

Acredito que funcione para mim e, dependendo de você, você poderá fazer algo como:

.aftersubmit(function(){
    stopPropigation()// or some other code which would prevent a refresh.
});
Fallenreaper
fonte
Não vejo como isso melhora qualquer outra resposta dada anteriormente. Também é Propagação, não Propagação ! ;)
JDuarteDJ