Питання Як я можу завантажувати файли асинхронно?


Я хотів би завантажити файл асинхронно з 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 завантажувати файли.


2609
2017-10-03 10:22


походження


ви отримуєте лише назву файлу, тому що ваш файл var має значення $ ('# file'), а не файл, який знаходиться на вході - Jimmy
Ось хороший: http://blueimp.github.io/jQuery-File-Upload/ - Завантаження ajax-файлів у форматі HTML5 - Витончений резервний доступ до iframes для непідтримуваних браузерів - Завантаження асинхронного файлу в декілька файлів Ми використали його, і це чудово працює. (Документація тут) - Ashish Panery
Плагін jQuery Form представляється найпростішим у використанні та сумісним із крос-браузером ... я прав? - Lyth
Перевірте також це: stackoverflow.com/questions/6974684/..., тут він пояснює, як це досягти через jQuery - Chococroc
@Jimmy Як би він отримав файл, який лежить у вводі? - alex


Відповіді:


З HTML5 ви можете завантажити файли з Ajax і jQuery. Крім того, ви можете перевіряти файли (ім'я, розмір і тип MIME) або обробляти події прогресу з тегом прогресу HTML5 (або розділом). Нещодавно мені довелося зробити завантажувач файлів, але я не хотів їх використовувати Flash ні в ІФАРМАХ, ні в плагінах, а після деяких досліджень я вирішив.

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 представить, натиснувши кнопку:

$(':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 з прикладів недоступні в кожному веб-переглядачі.


2336
2018-01-06 13:34



Чи можу я потім використовувати $ _FILES у файлі upload.php? - Alessandro Cosentino
Це повинно працювати в Internet Explorer, але лише у версії 10. (caniuse.com/xhr2) - Samir
Не працює в IE7-9 - KevinDeus
Привіт, я ціную, що PHP - це ваша мова вибору ... але мені цікаво, чи знаєте ви, чи це також працює в ASP.NET MVC? Я розробник. NET, і я спробував використати ваш простий приклад, щоб зробити деяку завантаження файлу AJAX, але на стороні сервера я не отримую файл, який я розмістив через AJAX. Я використовую останню версію Chrome. - Shumii
Його FormData хто робить тут всю магію. Обов'язково перевірте ці документи - він охоплює все ваше питання про декілька файлів і полів. - incarnate


Існують різні готові плагіни для завантаження файлів для jQuery.

Використання подібних завантажуваних хаків не є приємним досвідом, тому люди можуть насолоджуватися використанням готових рішень.

Ось кілька:

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


335
2017-10-15 10:35



Здається, що AjaxFUP-лінк порушив. Я підозрюю, що це те, на що посилається: valums.com/ajax-upload - UlfR
Ще одне читання - плагін завжди існує Filepicker.io, що дуже приємно тим, що він стосується всіх неприємних великих проблем з підтримкою файлів тощо. - brettcvz
Це насправді лише близько 10 рядків ванільного JS. Це насправді не так вже й погано. - mpen
Плагін для готових рішень може працювати чудово, але це не допомагає через деякий час, коли ви дізнаєтеся, що він не працює, ви думаєте, що це буде, і вам довелося зламати його незнайомими скриптами. Отже, це йде в обох напрямках. - fletchsod
Чи можу я використовувати JQuery File Uploader для кількох відео ..? буде підтримувати ..? - Mr world wide


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

Важливо розуміти з "новим" HTML5 file API це те, що є не підтримується до IE 10. Якщо конкретний ринок, на який ви прагнете, має більш високу, ніж у середньому, перевагу щодо старих версій Windows, можливо, ви не матимете доступу до нього.

У 2017 році приблизно 5% браузерів - це IE 6, 7, 8 або 9. Якщо ви перейдете у велику корпорацію (наприклад, це інструмент B2B або те, що ви доставляєте для навчання), ця цифра може ракети. Лише кілька місяців тому - в 2016 році - я займався компанією, що використовує IE8, на більш ніж 60% своїх машин.

Отже, перш ніж робити що-небудь: перевірте, який браузер твій користувачі користуються. Якщо ви цього не зробите, ви дізнаєтесь швидкий та болісний урок про те, чому "працює для мене" не є достатньою продуктивністю для клієнта.

Моя відповідь з 2008 року слідує.


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

Це "реальний" пост, тому він не є повністю інтерактивним. Якщо вам потрібен статус, вам потрібно щось обробляти на сервері. Це залежить від сервера вагомим чином. ASP.NET має більш гарні механізми. PHP просто не вдається, але ви можете використовувати Perl або модифікації Apache, щоб обійти це.

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

Або скористайтеся рішенням Java / Flash. Вони набагато гнучкі у тому, що вони можуть робити зі своїми публікаціями ...


237
2017-10-03 10:41



Для запису тепер можна робити чисті завантаження файлів AJAX, якщо браузер підтримує файл API - developer.mozilla.org/en/using_files_from_web_applications - meleyal
Якщо вам не потрібна підтримка IE9. caniuse.com/fileapi - Oli
Рішення iframe досить просте і легко працювати - Matthew Lock
це досить стара відповідь, але вона була дещо помилковою .. IE підтримує XHR спочатку ще в IE7, і підтримує її через ActiveX ще в IE5. w3schools.com/ajax/ajax_xmlhttprequest_create.asp. Практичний спосіб це зробити - це, безумовно, орієнтація на компоненти спалаху (ударну хвилю) або керування Flash / ActiveX (Silverlight). Якщо ви можете створити запит і керувати відповіддю за допомогою javascript, це є ajax .. хоча, зазначивши це, ajax є синонімом xhr, але він сам не описує підкреслення механізму / компонентів, які забезпечують / обмінюють корисне навантаження. - Brett Caswell
@BrettCaswell Я не казав, що AJAX / XHR не було можливим, просто неможливо розмістити файл з ними на старих, але коли-небудь живих версіях IE. Це було і залишається цілком вірним. - Oli


Я рекомендую використовувати Тонкий завантажувач плагін для цієї мети. Твій JavaScript код буде:

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

105
2017-11-21 16:38



Він використовує JSON - так для старої версії PHP це буде неможливо використовувати. - Lorenzo Manucci
Схоже набагато чистіше, ніж завантаження файлів Ajax, де мені потрібно включити величезну частину коду, щоб просто використати прокляту річ. - ripper234
URL-адреса зараз valums.com/ajax-upload. - Patrick Fisher
"Цей плагін відкритий за GNU GPL 2 або пізнішої версії та GNU LGPL 2 або пізнішої версії." Таким чином, поки ви не поширюєте копію чи модифіковану версію, вам не потрібно відкривати ваш проект. - Trantor Liu
Це веб-сайт (fineuploader.com) Я знайшов зараз, це V4.2. - Andrew_1510


Примітка. Ця відповідь застаріла, тепер можна завантажувати файли за допомогою XHR.


Ви не можете завантажувати файли за допомогою XMLHttpRequest (Ajax). Ви можете імітувати ефект за допомогою iframe або Flash. Відмінний Плагін форми jQuery що надсилає ваші файли через iFrame, щоб отримати ефект.


87
2017-10-03 10:36



Так, ви можете відправити POST в IFRAME і сфотографувати там файл. Однак у мене дуже обмежений досвід із цим, тому я не можу на це коментувати. - Mattias
Мале зауваження: в останніх версіях chrome і firefox можна, stackoverflow.com/questions/4856917/... - Alleo


Це Завантажити файл AJAX jQuery плагін завантажує файл де-небудь, і передає його відповідь на зворотний виклик, нічого більше.

  • Це не залежить від конкретного HTML, просто дайте йому a <input type="file">
  • Він не вимагає від вашого сервера реагування будь-яким особливим способом
  • Неважливо, скільки файлів ви використовуєте або де вони знаходяться на сторінці

- Використовувати як мало -

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

- або так само, як -

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

81
2017-07-29 00:34



Не працює з 1.9.1: | - user840250
@ user840250 jQuery 1.9.1? - Jordan Feldstein


Обгортання для майбутніх читачів.

Асинхронний завантаження файлів

З HTML5

Ви можете завантажувати файли з jQuery використовуючи $.ajax() метод, якщо FormData і API файлів підтримуються (обидва функції HTML5).

Ви також можете відправити файли без FormData але в будь-якому випадку Файловий API повинен бути присутнім для обробки файлів таким чином, щоб їх можна було надіслати 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!");
});

Для швидкого чистого JavaScript (немає jQuery) приклад см. "Відправка файлів за допомогою об'єкта FormData".

Відступати

Коли HTML5 не підтримується (немає API файлів) Єдиний інший чистий JavaScript-рішення (ні Flash або будь-який інший плагін браузера) є прихована IFRAME техніка, яка дозволяє емулювати асинхронний запит без використання XMLHttpRequest об'єкт

Він складається з встановлення iframe як цілі форми з файлами. Коли користувач подає запит, і файли завантажуються, але відповідь відображається всередині iframe, а не на повторному рендерингу головної сторінки. Приховування iframe робить весь процес прозорим для користувача та імітує асинхронний запит.

Якщо це зроблено належним чином, він повинен працювати практично в будь-якому браузері, але в ньому є певні застереження щодо отримання відповіді від iframe.

У цьому випадку ви можете скористатись плагіном обгортки, як Біфоруст який використовує техніка iframe але також забезпечує a jQuery Ajax транспорт дозволяючи відправляти файли з тільки $.ajax() спосіб подібний:

$.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!");
});

Плагіни

Біфоруст це лише невелика обгортка, яка додає резервну підтримку методу ajax jQuery, але багато хто з вищезгаданих плагінів люблять Плагін форми jQueryабо Завантаження файлу jQuery включати в себе весь стек від HTML5 до різних відмов та деяких корисних функцій для полегшення процесу. Залежно від ваших потреб та вимог ви можете розглянути голу реалізацію або будь-який з цих плагінів.


75
2017-08-25 14:17



Одне слід відзначити, на підставі документації: ви також повинні надіслати contentType: false. Коли я не надіслав це за допомогою chrome, тип вмісту форми не визнавався jQuery. - ash
Хороша відповідь. Кілька пропозицій щодо вдосконалення: видаліть частини коду, не пов'язані з відповіддю, наприклад .done() і .fail() зворотні виклики. Також, приклад без використання FormData і список про / мінусів буде чудовим. - Zero3
Я отримав цю помилку: TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement. - candlejack


Я використав скрипт нижче, щоб завантажувати зображення, які працюють нормально.

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

Пояснення

Я використовую відповідь div щоб показати завантажену анімацію та відповідь після завантаження.

Найкраще, якщо ви використовуєте цей сценарій, ви можете надсилати додаткові дані, такі як ідентифікатори та ін. Я згадую це extra-data як у скрипті.

На рівні PHP це буде працювати як звичайне завантаження файлів. додаткові дані можна отримати як $_POST дані

Тут ви не використовуєте плагін та інше. Ви можете змінити код, як ви хочете. Ви не сліпо кодуєте тут. Це основна функція будь-якого завантаження файлу jQuery. Власне, Javascript.


57
2018-01-25 11:03



-1 для використання jQuery і не використання його селекторного движка та обробників подій. addEventListener не є крос-браузером. - Mark
Тому що було б безглуздо додати окрему відповідь, яка б основному базувалася на цьому, лише з кількома змінами. Замість цього цю відповідь слід виправити. - Mark
@ RainFromHeaven, будь ласка, чи можете ви відредагувати відповідь? Я не знаю, як це робити через крос-браузерний спосіб. - Thiago Negri
Все ще не працює в IE 9 і вниз. Присвоєння користувачами все ще використовує ці версії IE. - Pierre
Чи може хтось пояснити, як це може бути зроблено для роботи в asp.net? Чи можу я використовувати webmethod? Якщо так, то як би це виглядало? - Arbaaz


Я зіткнувся з декількома дуже потужними бібліотеками завантаження файлів на основі jQuery. Перевірте це:

  1. Завантажити
  2. Завантаження файлу jQuery
  3. FineUploader

55
2018-04-08 16:43





Ви можете завантажувати просто за допомогою 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
2017-08-08 02:59



спасибі, це робота над завантаженням файлів .xls - Tarek Kalaji
Яку бібліотеку jQuery мені потрібно, щоб запустити цей код? - Rayden Black
@RaydenBlack тільки jQuery. - Zayn Ali
як отримати завантаження? - Ali Sherafat
@AliSherafat я оновив мою відповідь. Спробуй це - Zayn Ali