Вопрос: Как я могу загружать файлы асинхронно?


Я хотел бы загрузить файл асинхронно с помощью jQuery. Это мой HTML:

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

И здесь мой 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: ");
            }
        });
    });
});

Вместо загружаемого файла я получаю только имя файла. Что я могу сделать, чтобы исправить эту проблему?

Текущее решение

Я использую Плагин формы jQuery для загрузки файлов.


2577


источник


Ответы:


С HTML5 вы можете сделать загрузку файлов с помощью Ajax и jQuery. Кроме того, вы можете выполнять проверки файлов (имя, размер и тип MIME) или обрабатывать событие прогресса с тегом прогресса HTML5 (или div). Недавно мне пришлось сделать загрузчик файлов, но я не хотел использовать вспышка ни iframes, ни плагинов, и после некоторых исследований я придумал решение.

HTML:

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

Во-первых, вы можете сделать некоторую проверку, если хотите. Например, в событии onChange файла:

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

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

Теперь Ajax submit с нажатием кнопки:

$(':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;
        }
    });
});

Как вы можете видеть, с HTML5 (и некоторым исследованием) загрузка файлов не только становится возможной, но и очень простой. Попробуйте Гугл Хром поскольку некоторые из компонентов HTML5 в примерах недоступны в каждом браузере.


2322



Существуют различные готовые плагины для загрузки файлов для jQuery.

Выполнение такого рода загрузочных хаков - не приятный опыт, поэтому людям нравится использовать готовые решения.

Вот несколько:

Вы можете искать больше проектов на NPM (используя «jquery-plugin» в качестве ключевого слова) или на Github.


330



2017 Обновление: все равно зависит от браузеров ваш демографического использования.

Важно понять «новый» HTML5 fileAPI - это не поддерживался до IE 10 , Если конкретный рынок, на который вы нацеливаетесь, имеет более высокую, чем среднюю, предел для более старых версий Windows, у вас может не быть доступа к нему.

Начиная с 2017 года, около 5% браузеров являются одним из IE 6, 7, 8 или 9. Если вы направляетесь в большую корпорацию (например, это инструмент B2B или что-то, что вы доставляете для обучения), это число может ракета. Всего несколько месяцев назад - в 2016 году - я имел дело с компанией, использующей IE8 на более чем 60% своих машин.

Итак, прежде чем что-либо сделать: проверить, какой браузер ваш пользователи используют , Если вы этого не сделаете, вы научитесь быстрому и мучительному уроку в том, почему «работает для меня» недостаточно хорош для доставки клиенту.

Мой ответ от 2008 года.


Тем не менее, существуют жизнеспособные не-JS-методы загрузки файлов. Вы можете создать iframe на странице (которую вы скрываете с помощью CSS), а затем настроить таргетинг своей формы для публикации в iframe. На главной странице не нужно двигаться.

Это «реальный» пост, поэтому он не является полностью интерактивным. Если вам нужен статус, вам нужно что-то серверное для его обработки. Это зависит от вашего сервера. ASP.NET имеет более хорошие механизмы. Ошибка PHP plain, но вы можете использовать Perl или Apache, чтобы обойти его.

Если вам нужно несколько загрузок файлов, лучше делать каждый файл по одному (чтобы преодолеть максимальные пределы загрузки файлов). Отправляйте первую форму в iframe, отслеживайте ее прогресс, используя вышеприведенное и когда он закончил, разместите вторую форму в iframe и т. Д.

Или используйте решение Java / Flash. Они намного более гибки в том, что они могут делать со своими постами ...


233



I recommend using the Fine Uploader plugin for this purpose. Your JavaScript code would be:

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

104



Note: This answer is outdated, it is now possible to upload files using XHR.


You cannot upload files using XMLHttpRequest (Ajax). You can simulate the effect using an iframe or Flash. The excellent jQuery Form Plugin that posts your files through an iframe to get the effect.


85



This AJAX file upload jQuery plugin uploads the file somehwere, and passes the response to a callback, nothing else.

  • It does not depend on specific HTML, just give it a <input type="file">
  • It does not require your server to respond in any particular way
  • It does not matter how many files you use, or where they are on the page

-- Use as little as --

$('#one-specific-file').ajaxfileupload({
  'action': '/upload.php'
});

-- or as much as --

$('input[type="file"]').ajaxfileupload({
  'action': '/upload.php',
  'params': {
    'extra': 'info'
  },
  'onComplete': function(response) {
    console.log('custom handler for file:');
    alert(JSON.stringify(response));
  },
  'onStart': function() {
    if(weWantedTo) return false; // cancels upload
  },
  'onCancel': function() {
    console.log('no file selected');
  }
});

80



Wrapping up for future readers.

Asynchronous File Upload

With HTML5

You can upload files with jQuery using the $.ajax() method if FormData and the File API are supported (both HTML5 features).

You can also send files without FormData but either way the File API must be present to process files in such a way that they can be sent with 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!");
});

For a quick, pure JavaScript (no jQuery) example see "Sending files using a FormData object".

Fallback

When HTML5 isn't supported (no File API) the only other pure JavaScript solution (no Flash or any other browser plugin) is the hidden iframe technique, which allows to emulate an asynchronous request without using the XMLHttpRequest object.

It consists of setting an iframe as the target of the form with the file inputs. When the user submits a request is made and the files are uploaded but the response is displayed inside the iframe instead of re-rendering the main page. Hiding the iframe makes the whole process transparent to the user and emulates an asynchronous request.

If done properly it should work virtually on any browser, but it has some caveats as how to obtain the response from the iframe.

In this case you may prefer to use a wrapper plugin like Bifröst which uses the iframe technique but also provides a jQuery Ajax transport allowing to send files with just the $.ajax() method like this:

$.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 is just a small wrapper that adds fallback support to jQuery's ajax method, but many of the aforementioned plugins like jQuery Form Plugin or jQuery File Upload include the whole stack from HTML5 to different fallbacks and some useful features to ease out the process. Depending on your needs and requirements you might want to consider a bare implementation or either of this plugins.


73



I have been using the below script to upload images which happens to work fine.

HTML

<input id="file" type="file" name="file"/>
<div id="response"></div>

JavaScript

jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

Explanation

I use response div to show the uploading animation and response after upload is done.

Best part is you can send extra data such as ids & etc with the file when you use this script. I have mention it extra-data as in the script.

At the PHP level this will work as normal file upload. extra-data can be retrieved as $_POST data.

Here you are not using a plugin and stuff. You can change the code as you want. You are not blindly coding here. This is the core functionality of any jQuery file upload. Actually Javascript.


57



I've come across a few really powerful jQuery-based file upload libraries. Check these out:

  1. Plupload
  2. jQuery File Upload
  3. FineUploader

55



You can upload simply with jQuery .ajax().

HTML:

<form id="upload-form">
    <div>
        <label for="file">File:</label>
        <input type="file" id="file" name="file" />
        <progress class="progress" value="0" max="100"></progress>
    </div>
    <hr />
    <input type="submit" value="Submit" />
</form>

CSS

.progress { display: none; }

Javascript:

$(document).ready(function(ev) {
    $("#upload-form").on('submit', (function(ev) {
        ev.preventDefault();
        $.ajax({
            xhr: function() {
                var progress = $('.progress'),
                    xhr = $.ajaxSettings.xhr();

                progress.show();

                xhr.upload.onprogress = function(ev) {
                    if (ev.lengthComputable) {
                        var percentComplete = parseInt((ev.loaded / ev.total) * 100);
                        progress.val(percentComplete);
                        if (percentComplete === 100) {
                            progress.hide().val(0);
                        }
                    }
                };

                return xhr;
            },
            url: 'upload.php',
            type: 'POST',
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(data, status, xhr) {
                // ...
            },
            error: function(xhr, status, error) {
                // ...
            }
       });
    }));
});

42



You can do it in vanilla JavaScript pretty easily. Here's a snippet from my current project:

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);

40