javascript - with - upload file to server jquery




Como posso carregar arquivos de forma assíncrona? (20)

Atualização de 2017: ainda depende dos navegadores usados ​​pelos usuários.

Uma coisa importante para entender com a "nova" API do file HTML5 é que ela não é suportada até o IE 10 . Se o mercado específico que você está mirando tem uma preponderância acima da média em relação às versões mais antigas do Windows, talvez você não tenha acesso a ele.

Em 2017, cerca de 5% dos navegadores são do IE 6, 7, 8 ou 9. Se você se depara com uma grande corporação (por exemplo, uma ferramenta B2B, ou algo que você está oferecendo para treinamento), esse número pode disparar. Apenas alguns meses atrás - em 2016 - eu lidei com uma empresa usando o IE8 em mais de 60% de suas máquinas.

Portanto, antes de fazer qualquer coisa: verifique qual navegador seus usuários usam . Se não o fizer, você aprenderá uma lição rápida e dolorosa sobre por que "funciona para mim" não é bom o suficiente em uma entrega para um cliente.

Minha resposta de 2008 segue.

No entanto, existem métodos não-viáveis ​​de uploads de arquivos. Você pode criar um iframe na página (que você esconde com CSS) e depois segmentar seu formulário para postar nesse iframe. A página principal não precisa se mover.

É um post "real", por isso não é totalmente interativo. Se você precisa de status, você precisa de algo do lado do servidor para processar isso. Isso varia enormemente dependendo do seu servidor. ASP.NET tem mecanismos mais agradáveis. O PHP plain falha, mas você pode usar as modificações Perl ou Apache para contornar isso.

Se você precisar de vários uploads de arquivos, é melhor fazer cada arquivo um de cada vez (para superar os limites máximos de upload de arquivos). Poste o primeiro formulário no iframe, monitore seu progresso usando o acima e, quando terminar, poste o segundo formulário no iframe e assim por diante.

Ou use uma solução Java / Flash. Eles são muito mais flexíveis no que podem fazer com seus posts ...

Eu gostaria de fazer upload de um arquivo de forma assíncrona com jQuery. Este é meu HTML:

<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

E aqui meu código Jquery :

$(document).ready(function () {
    $("#uploadbutton").click(function () {
        var filename = $("#file").val();

        $.ajax({
            type: "POST",
            url: "addFile.do",
            enctype: 'multipart/form-data',
            data: {
                file: filename
            },
            success: function () {
                alert("Data Uploaded: ");
            }
        });
    });
});

Em vez do arquivo que está sendo carregado, estou recebendo apenas o nome do arquivo. O que posso fazer para corrigir este problema?

Solução Atual

Eu estou usando o jQuery Form Plugin para fazer upload de arquivos.


A maneira mais simples e mais robusta que fiz no passado é simplesmente segmentar uma tag iFrame oculta com o seu formulário - então ela será enviada dentro do iframe sem recarregar a página.

Isto é, se você não quiser usar um plugin, JavaScript ou qualquer outra forma de "mágica" que não seja HTML. Claro que você pode combinar isso com JavaScript ou o que você tem ...

<form target="iframe" action="" method="post" enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

<iframe name="iframe" id="iframe" style="display:none" ></iframe>

Você também pode ler o conteúdo do iframe onLoad para erros do servidor ou respostas de sucesso e, em seguida, enviar a saída para o usuário.

Chrome, iFrames e onLoad

-note-você só precisa continuar lendo se você estiver interessado em como configurar um bloqueador de UI ao fazer o upload / download

Atualmente, o Chrome não aciona o evento onLoad para o iframe quando é usado para transferir arquivos. Firefox, IE e Edge todos disparam o evento onload para transferências de arquivos.

A única solução que encontrei funciona para o Chrome foi usar um cookie.

Para fazer isso basicamente quando o upload / download é iniciado:

  • [Lado do cliente] Inicie um intervalo para procurar a existência de um cookie
  • [Lado do servidor] Faça o que precisar com os dados do arquivo
  • [Lado do servidor] Definir cookie para o intervalo do lado do cliente
  • O [Client Side] Interval vê o cookie e o usa como o evento onLoad. Por exemplo, você pode iniciar um bloqueador de UI e, em seguida, onLoad (ou quando o cookie é feito) você remove o bloqueador de UI.

Usar um cookie para isso é feio, mas funciona.

Eu fiz um plugin jQuery para lidar com esse problema para o Chrome ao baixar, você pode encontrar aqui

https://github.com/ArtisticPhoenix/jQuery-Plugins/blob/master/iDownloader.js

O mesmo princípio básico se aplica ao upload também.

Para usar o downloader (inclua o JS, obviamente)

 $('body').iDownloader({
     "onComplete" : function(){
          $('#uiBlocker').css('display', 'none'); //hide ui blocker on complete
     }
 });

 $('somebuttion').click( function(){
      $('#uiBlocker').css('display', 'block'); //block the UI
      $('body').iDownloader('download', 'htttp://example.com/location/of/download');
 });

E no lado do servidor, pouco antes de transferir os dados do arquivo, crie o cookie

 setcookie('iDownloader', true, time() + 30, "/");

O plug-in verá o cookie e, em seguida, acionará o retorno de chamada onComplete .


Com o HTML5 você pode fazer upload de arquivos com o Ajax e o jQuery. Além disso, você pode fazer validações de arquivos (nome, tamanho e tipo MIME) ou manipular o evento progress com a tag de progresso HTML5 (ou div). Recentemente eu tive que fazer um uploader de arquivos, mas eu não queria usar Flash nem Iframes ou plugins e depois de alguma pesquisa eu encontrei a solução.

O HTML:

<form enctype="multipart/form-data">
    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>
<progress></progress>

Primeiro, você pode fazer alguma validação, se quiser. Por exemplo, no evento onChange do arquivo:

$(':file').on('change', function() {
    var file = this.files[0];
    if (file.size > 1024) {
        alert('max upload size is 1k')
    }

    // Also see .name, .type
});

Agora o Ajax envia com o clique do botão:

$(':button').on('click', function() {
    $.ajax({
        // Your server script to process the upload
        url: 'upload.php',
        type: 'POST',

        // Form data
        data: new FormData($('form')[0]),

        // Tell jQuery not to process data or worry about content-type
        // You *must* include these options!
        cache: false,
        contentType: false,
        processData: false,

        // Custom XMLHttpRequest
        xhr: function() {
            var myXhr = $.ajaxSettings.xhr();
            if (myXhr.upload) {
                // For handling the progress of the upload
                myXhr.upload.addEventListener('progress', function(e) {
                    if (e.lengthComputable) {
                        $('progress').attr({
                            value: e.loaded,
                            max: e.total,
                        });
                    }
                } , false);
            }
            return myXhr;
        }
    });
});

Como você pode ver, com o upload de arquivos em HTML5 (e algumas pesquisas), não só se torna possível, mas super fácil. Experimente com o Google Chrome, pois alguns dos componentes HTML5 dos exemplos não estão disponíveis em todos os navegadores.


Conclusão para futuros leitores.

Upload de arquivo assíncrono

Com HTML5

Você pode carregar arquivos com jQuery usando o método $.ajax() se FormData e a API File forem suportados (ambos os recursos HTML5).

Você também pode enviar arquivos sem FormData, mas de qualquer forma, a API File deve estar presente para processar arquivos de forma que eles possam ser enviados com XMLHttpRequest (Ajax).

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  data: new FormData($('#formWithFiles')[0]), // The form with the file inputs.
  processData: false,
  contentType: false                    // Using FormData, no need to process data.
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Para um exemplo rápido e puro de JavaScript ( sem jQuery ), consulte " Enviando arquivos usando um objeto FormData ".

Cair pra trás

Quando HTML5 não é suportado (nenhuma API de arquivo ), a única outra solução JavaScript pura (sem Flash ou qualquer outro plug-in de navegador) é a técnica de iframe oculto , que permite emular uma solicitação assíncrona sem usar o objeto XMLHttpRequest .

Consiste em definir um iframe como o destino do formulário com as entradas do arquivo. Quando o usuário envia uma solicitação é feita e os arquivos são enviados, mas a resposta é exibida dentro do iframe, em vez de renderizar novamente a página principal. Ocultar o iframe torna todo o processo transparente para o usuário e emula uma solicitação assíncrona.

Se feito corretamente, deve funcionar virtualmente em qualquer navegador, mas tem algumas ressalvas de como obter a resposta do iframe.

Neste caso, você pode preferir usar um plugin wrapper como o Bifröst que usa a técnica iframe, mas também fornece um transporte jQuery Ajax, permitindo enviar arquivos apenas com o método $.ajax() , da seguinte maneira:

$.ajax({
  url: 'file/destination.html', 
  type: 'POST',
  // Set the transport to use (iframe means to use Bifröst)
  // and the expected data type (json in this case).
  dataType: 'iframe json',                                
  fileInputs: $('input[type="file"]'),  // The file inputs containing the files to send.
  data: { msg: 'Some extra data you might need.'}
}).done(function(){
  console.log("Success: Files sent!");
}).fail(function(){
  console.log("An error occurred, the files couldn't be sent!");
});

Plugins

Bifröst é apenas um pequeno wrapper que adiciona suporte de fallback ao método ajax do jQuery, mas muitos dos plugins mencionados acima, como jQuery Form Plugin ou jQuery File Upload, incluem toda a pilha de HTML5 a diferentes fallbacks e alguns recursos úteis para facilitar o processo. Dependendo de suas necessidades e requisitos, talvez você queira considerar uma implementação simples ou um desses plug-ins.



Eu recomendo usar o plugin Fine Uploader para esse propósito. Seu código JavaScript seria:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});


Nota: Esta resposta está desatualizada, agora é possível fazer upload de arquivos usando o XHR.

Você não pode carregar arquivos usando XMLHttpRequest (Ajax). Você pode simular o efeito usando um iframe ou Flash. O excelente jQuery Form Plugin que publica seus arquivos através de um iframe para obter o efeito.


Uma solução que encontrei foi fazer com que o <form> visasse um iFrame oculto. O iFrame pode então executar o JS para mostrar ao usuário que ele está completo (no carregamento da página).


Você pode fazê-lo no JavaScript de baunilha com bastante facilidade. Aqui está um trecho do meu projeto atual:

var xhr = new XMLHttpRequest();
xhr.upload.onprogress = function(e) {
    var percent = (e.position/ e.totalSize);
    // Render a pretty progress bar
};
xhr.onreadystatechange = function(e) {
    if(this.readyState === 4) {
        // Handle file upload complete
    }
};
xhr.open('POST', '/upload', true);
xhr.setRequestHeader('X-FileName',file.name); // Pass the filename along
xhr.send(file);

Você pode usar

$(function() {
    $("#file_upload_1").uploadify({
        height        : 30,
        swf           : '/uploadify/uploadify.swf',
        uploader      : '/uploadify/uploadify.php',
        width         : 120
    });
});

Demo


jQuery Uploadify é outro bom plugin que eu usei antes para fazer upload de arquivos. O código JavaScript é tão simples quanto o seguinte: código. No entanto, a nova versão não funciona no Internet Explorer.

$('#file_upload').uploadify({
    'swf': '/public/js/uploadify.swf',
    'uploader': '/Upload.ashx?formGuid=' + $('#formGuid').val(),
    'cancelImg': '/public/images/uploadify-cancel.png',
    'multi': true,
    'onQueueComplete': function (queueData) {
        // ...
    },
    'onUploadStart': function (file) {
        // ...
    }
});

Eu fiz muita pesquisa e cheguei a outra solução para fazer upload de arquivos sem qualquer plugin e apenas com ajax. A solução é como abaixo:

$(document).ready(function () {
    $('#btn_Upload').live('click', AjaxFileUpload);
});

function AjaxFileUpload() {
    var fileInput = document.getElementById("#Uploader");
    var file = fileInput.files[0];
    var fd = new FormData();
    fd.append("files", file);
    var xhr = new XMLHttpRequest();
    xhr.open("POST", 'Uploader.ashx');
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
             alert('success');
        }
        else if (uploadResult == 'success')
            alert('error');
    };
    xhr.send(fd);
}

Esta é minha solução.

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

e o js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

Controlador

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    return Json(":)");
}

Para fazer upload de arquivos de forma assíncrona com o Jquery, use as etapas abaixo:

passo 1 No seu projeto abra o gerenciador Nuget e adicione o pacote (jquery fileupload (apenas você precisa escrevê-lo na caixa de pesquisa e ele irá instalá-lo.)) URL: https://github.com/blueimp/jQuery-File- Envio

step 2 Adicione abaixo os scripts nos arquivos HTML, que já estão adicionados ao projeto executando o pacote acima:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

passo 3 Grave o controle de upload de arquivo de acordo com o código abaixo:

<input id="upload" name="upload" type="file" />

passo 4 escreva um método js como uploadFile como abaixo:

 function uploadFile(element) {

            $(element).fileupload({

                dataType: 'json',
                url: '../DocumentUpload/upload',
                autoUpload: true,
                add: function (e, data) {           
                  // write code for implementing, while selecting a file. 
                  // data represents the file data. 
                  //below code triggers the action in mvc controller
                  data.formData =
                                    {
                                     files: data.files[0]
                                    };
                  data.submit();
                },
                done: function (e, data) {          
                   // after file uploaded
                },
                progress: function (e, data) {

                   // progress
                },
                fail: function (e, data) {

                   //fail operation
                },
                stop: function () {

                  code for cancel operation
                }
            });

        };

passo 5 No upload do arquivo de elemento de chamada de função pronto para iniciar o processo conforme abaixo:

$(document).ready(function()
{
    uploadFile($('#upload'));

});

etapa 6 Escreva o controlador MVC e a ação como por abaixo:

public class DocumentUploadController : Controller
    {       

        [System.Web.Mvc.HttpPost]
        public JsonResult upload(ICollection<HttpPostedFileBase> files)
        {
            bool result = false;

            if (files != null || files.Count > 0)
            {
                try
                {
                    foreach (HttpPostedFileBase file in files)
                    {
                        if (file.ContentLength == 0)
                            throw new Exception("Zero length file!");                       
                        else 
                            //code for saving a file

                    }
                }
                catch (Exception)
                {
                    result = false;
                }
            }


            return new JsonResult()
                {
                    Data=result
                };


        }

    }

Exemplo: Se você usar o jQuery, poderá fazer facilmente um arquivo de upload. Este é um pequeno e forte plugin jQuery, http://jquery.malsup.com/form/ .

Exemplo

var $bar   = $('.ProgressBar');
$('.Form').ajaxForm({
  dataType: 'json',

  beforeSend: function(xhr) {
    var percentVal = '0%';
    $bar.width(percentVal);
  },

  uploadProgress: function(event, position, total, percentComplete) {
    var percentVal = percentComplete + '%';
    $bar.width(percentVal)
  },

  success: function(response) {
    // Response
  }
});

Espero que seja útil


Procure Manuseando o processo de upload de um arquivo de forma assíncrona aqui: https://developer.mozilla.org/pt-BR/docs/Using_files_from_web_applications

Amostra do link

<?php
if (isset($_FILES['myFile'])) {
    // Example:
    move_uploaded_file($_FILES['myFile']['tmp_name'], "uploads/" . $_FILES['myFile']['name']);
    exit;
}
?><!DOCTYPE html>
<html>
<head>
    <title>dnd binary upload</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script type="text/javascript">
        function sendFile(file) {
            var uri = "/index.php";
            var xhr = new XMLHttpRequest();
            var fd = new FormData();

            xhr.open("POST", uri, true);
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    // Handle response.
                    alert(xhr.responseText); // handle response.
                }
            };
            fd.append('myFile', file);
            // Initiate a multipart/form-data upload
            xhr.send(fd);
        }

        window.onload = function() {
            var dropzone = document.getElementById("dropzone");
            dropzone.ondragover = dropzone.ondragenter = function(event) {
                event.stopPropagation();
                event.preventDefault();
            }

            dropzone.ondrop = function(event) {
                event.stopPropagation();
                event.preventDefault();

                var filesArray = event.dataTransfer.files;
                for (var i=0; i<filesArray.length; i++) {
                    sendFile(filesArray[i]);
                }
            }
        }
    </script>
</head>
<body>
    <div>
        <div id="dropzone" style="margin:30px; width:500px; height:300px; border:1px dotted grey;">Drag & drop your file here...</div>
    </div>
</body>
</html>

Usando HTML5 e JavaScript , fazer o upload do async é bem fácil, eu crio a lógica de upload junto com o seu html, isso não está funcionando completamente pois precisa da API, mas demonstra como funciona, se você tem o endpoint chamado /uploadfrom root do seu site, este código deve funcionar para você:

const asyncFileUpload = () => {
  const fileInput = document.getElementById("file");
  const file = fileInput.files[0];
  const uri = "/upload";
  const xhr = new XMLHttpRequest();
  xhr.upload.onprogress = e => {
    const percentage = e.loaded / e.total;
    console.log(percentage);
  };
  xhr.onreadystatechange = e => {
    if (xhr.readyState === 4 && xhr.status === 200) {
      console.log("file uploaded");
    }
  };
  xhr.open("POST", uri, true);
  xhr.setRequestHeader("X-FileName", file.name);
  xhr.send(file);
}
<form>
  <span>File</span>
  <input type="file" id="file" name="file" size="10" />
  <input onclick="asyncFileUpload()" id="upload" type="button" value="Upload" />
</form>

Além disso, algumas informações adicionais sobre XMLHttpReques:

O objeto XMLHttpRequest

Todos os navegadores modernos suportam o objeto XMLHttpRequest. O objeto XMLHttpRequest pode ser usado para trocar dados com um servidor da web nos bastidores. Isso significa que é possível atualizar partes de uma página da Web, sem recarregar a página inteira.


Crie um objeto XMLHttpRequest

Todos os navegadores modernos (Chrome, Firefox, IE7 +, Edge, Safari, Opera) têm um objeto XMLHttpRequest integrado.

Sintaxe para criar um objeto XMLHttpRequest:

variável = novo XMLHttpRequest ();


Acesso entre domínios

Por motivos de segurança, os navegadores modernos não permitem o acesso em vários domínios.

Isso significa que tanto a página da Web quanto o arquivo XML que ela tenta carregar devem estar localizados no mesmo servidor.

Os exemplos no W3Schools abrem todos os arquivos XML localizados no domínio W3Schools.

Se você quiser usar o exemplo acima em uma de suas próprias páginas da Web, os arquivos XML carregados devem estar localizados em seu próprio servidor.

Para mais detalhes, você pode continuar lendo here ...


Você pode fazer uploads de arquivos múltiplos assíncronos usando JavaScript ou jQuery e que sem usar qualquer plugin. Você também pode mostrar o progresso em tempo real do upload de arquivos no controle de progresso. Eu encontrei 2 links legais -

  1. Recurso de upload de arquivo múltiplo baseado em Web Forms do ASP.NET com barra de progresso
  2. Upload de arquivos múltiplos baseado em ASP.NET MVC feito em jQuery

A linguagem do lado do servidor é C #, mas você pode fazer algumas modificações para fazê-lo funcionar com outras linguagens como o PHP.

Upload de Arquivos ASP.NET Core MVC:

No controle de upload de criação de arquivos de visualização em html:

[HttpPost]
public async Task<IActionResult> Add(IFormFile[] mediaUpload)
{
    //looping through all the files
    foreach (IFormFile file in mediaUpload)
    {
        //saving the files
        string path = Path.Combine(hostingEnvironment.WebRootPath, "some-folder-path"); 
        using (var stream = new FileStream(path, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }
    }
}

Agora crie um método de ação no seu controlador:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}

A variável hostingEnvironment é do tipo IHostingEnvironment, que pode ser injetada no controlador usando a injeção de dependência, como:

$('#fileupload').fileupload({
    add: function (e, data) {
        var that = this;
        $.getJSON('/example/url', function (result) {
            data.formData = result; // e.g. {id: 123}
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    } 
});

Você pode usar a API de busca mais recente por JavaScript. Como isso:

<form method="post" asp-action="Add" enctype="multipart/form-data">
    <input type="file" multiple name="mediaUpload" />
    <button type="submit">Submit</button>
</form>

Vantagem: a API de busca é suportada nativamente por todos os navegadores modernos, portanto você não precisa importar nada. Além disso, observe que fetch () retorna um Promise que é então tratado de .then(..code to handle response..)forma assíncrona.


Você pode ver uma solução resolvida com uma demonstração de trabalho here que permite visualizar e enviar arquivos de formulário para o servidor. Para o seu caso, você precisa usar o Ajax para facilitar o upload do arquivo para o servidor:

<from action="" id="formContent" method="post" enctype="multipart/form-data">
    <span>File</span>
    <input type="file" id="file" name="file" size="10"/>
    <input id="uploadbutton" type="button" value="Upload"/>
</form>

Os dados enviados são um formdata. Em seu jQuery, use uma função de envio de formulário em vez de um clique de botão para enviar o arquivo de formulário, conforme mostrado abaixo.

$(document).ready(function () {
   $("#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("successfully submitted");

     });
   });
});

here





upload