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

Я хочу загрузить файл асинхронно с помощью 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: ");
            }
        });
    });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input id="uploadbutton" type="button" value="Upload"/>

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


person Sergio del Amo    schedule 03.10.2008    source источник
comment
Существуют различные готовые плагины для загрузки файлов для jQuery. Выполнение такого рода хаков для загрузки не доставляет удовольствия, поэтому людям нравится использовать готовые решения. Вот несколько: - JQuery File Uploader - Плагин для загрузки нескольких файлов - Мини-загрузка нескольких файлов - Загрузка файла jQuery Вы можете искать другие проекты на NPM (используя jquery-plugin в качестве ключевого слова) или на Github.   -  person Cheery    schedule 15.10.2008
comment
вы получаете только имя файла, потому что ваше имя файла var получает значение $ ('# file'), а не файл, который находится на входе   -  person Jimmy    schedule 03.11.2009
comment
Я наткнулся на несколько действительно мощных библиотек для загрузки файлов на основе jQuery. Проверьте это: 1. Plupload - docs: plupload.com/docs 2. Загрузка файла jQuery - документы: github.com/blueimp/jQuery-File-Upload 3. FineUploader - документы: docs.fineuploader.com   -  person Hristo    schedule 08.04.2011
comment
Вот хороший вариант: http://blueimp.github.io/jQuery-File-Upload/ - Загрузка HTML5 ajax - Изящный переход к iframe для неподдерживаемых браузеров - Асинхронная загрузка нескольких файлов Мы использовали его, и он отлично работает. (документация здесь)   -  person Ashish Panery    schedule 12.04.2013
comment
Также проверьте следующее: stackoverflow.com/questions/6974684/, здесь объясняется, как этого добиться с помощью jQuery.   -  person Federico J.    schedule 15.01.2014
comment
@ Джимми Как бы он вместо этого получил файл, который лежит на входе?   -  person alex    schedule 05.12.2014


Ответы (34)


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

HTML:

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

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

$(':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 (и некоторыми исследованиями) загрузка файлов не только становится возможной, но и очень простой. Попробуйте это с помощью Google Chrome, поскольку некоторые из компонентов HTML5 примеров доступны не во всех браузерах. .

person olanod    schedule 06.01.2012
comment
@ Silver89, если вы хотите вернуть данные из серверного скрипта, который вы установили в настройках URL-адреса (в данном случае 'upload.php'), ответом будет то, что вы напечатаете или отобразите в этом скрипте. Затем вы можете делать с данными все, что захотите. Проверьте ajaxComplete и аналогичные функции в jQuery Docs - person olanod; 13.05.2012
comment
У меня работает файловая часть ... но можете ли вы включить в нее текстовые поля? Это не похоже на var formData = new FormData($('form')[0]); или serialize()? - person Dan; 05.06.2012
comment
с новыми FormData ($ ('form') [0]); он должен работать, у вашего текстового поля есть имя? используйте print_r в $ _POST, чтобы убедиться, что данные есть, проверьте ответ на сетевом мониторе (хром), чтобы увидеть необработанный ответ. - person olanod; 05.06.2012
comment
Могу ли я использовать $ _FILES в файле upload.php? - person Alessandro Cosentino; 02.11.2012
comment
Это должно работать в Internet Explorer, но только в версии 10. (caniuse.com/xhr2) - person Tyler; 02.01.2013
comment
Привет, я ценю, что PHP - ваш предпочтительный язык ... но мне интересно, знаете ли вы, работает ли это также в ASP.NET MVC? Я разработчик .NET, и я попытался использовать ваш простой пример для загрузки некоторых файлов AJAX, но на стороне сервера я не получаю файл, который я отправил через AJAX. Я использую последнюю версию Chrome. - person Shumii; 01.06.2013
comment
Все волшебство здесь делает FormData. Обязательно ознакомьтесь с этими документами - они охватывают все ваши вопросы о нескольких файлах и полях. - person BorisOkunskiy; 12.09.2013

Обновление 2019: это по-прежнему зависит от браузеров, используемых демографическими пользователями.

При использовании «нового» file API HTML5 важно понимать, что он не поддерживался до IE 10. Если конкретный рынок, на который вы нацелены, имеет склонность к более старым версиям Windows выше среднего, у вас может не быть к нему доступа.

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

На момент этой правки 2019 год, спустя почти 11 лет после моего первоначального ответа. IE9 и ниже глобально находятся на отметке 1%, но все еще есть кластеры с более высоким использованием.

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

Мой ответ от 2008 года следует.


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

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

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

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

person Oli    schedule 03.10.2008
comment
Для записи теперь можно выполнять загрузку файлов с использованием чистого AJAX, если браузер поддерживает File API - developer.mozilla. org / en / using_files_from_web_applications - person meleyal; 25.03.2011
comment
это довольно старый ответ, но он немного вводит в заблуждение. IE изначально поддерживал XHR еще в IE7 и поддерживал его через ActiveX еще в IE5. http://www.w3schools.com/ajax/ajax_xmlhttprequest_create.asp. Практический способ сделать это определенно заключался в нацеливании на компоненты flash (ударной волны) или развертывании элемента управления Flash / ActiveX (Silverlight). Если вы можете создать запрос и обработать ответ через javascript, это ajax ... хотя, как уже говорилось, ajax является синонимом xhr, но сам по себе не описывает механизм / компоненты подчеркивания, которые доставляют / обменивают полезную нагрузку. - person Brett Caswell; 29.10.2015
comment
@BrettCaswell Я не говорил, что AJAX / XHR невозможно, просто невозможно было опубликовать файл с ними в старых, но вечно существующих версиях IE. Это было и остается полностью верным. - person Oli; 29.10.2015

Я рекомендую использовать для этой цели плагин Fine Uploader. Ваш JavaScript код будет:

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});
person Community    schedule 21.11.2008
comment
Этот плагин имеет открытый исходный код под GNU GPL 2 или новее и GNU LGPL 2 или новее. Итак, пока вы не распространяете копию или измененную версию, вам не нужно открывать свой проект. - person Trantor Liu; 23.07.2012

Примечание. Этот ответ устарел, теперь можно загружать файлы с помощью XHR.


Вы не можете загружать файлы с помощью XMLHttpRequest (Ajax). Эффект можно смоделировать с помощью iframe или Flash. Отличный jQuery Form Plugin, который отправляет ваши файлы через iframe для получения эффекта.

person Mattias    schedule 03.10.2008
comment
Небольшое замечание: в последних версиях Chrome и Firefox это возможно, stackoverflow.com/questions/4856917/ - person Alleo; 03.11.2011

Подведение итогов для будущих читателей.

Асинхронная загрузка файла

С HTML5

Вы можете загружать файлы с помощью jQuery с помощью метода $.ajax() if FormData и File 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 не поддерживается (без File API), единственным другим решением на чистом JavaScript (без Flash или любого другого подключаемого модуля браузера) является скрытый iframe , позволяющий эмулировать асинхронный запрос без использования объекта XMLHttpRequest.

Он состоит из установки iframe в качестве цели формы с входными данными файла. Когда пользователь отправляет запрос, выполняется загрузка файлов, но ответ отображается внутри iframe вместо повторного рендеринга главной страницы. Скрытие iframe делает весь процесс прозрачным для пользователя и имитирует асинхронный запрос.

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

В этом случае вы можете предпочесть использовать плагин-оболочку, например Bifröst, который использует технику iframe но также предоставляет транспорт 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!");
});

Плагины

Bifröst - это всего лишь небольшая оболочка, которая добавляет резервную поддержку метода jQuery ajax, но многие из вышеупомянутых плагинов, таких как плагин jQuery Form или Загрузка файла jQuery включает весь стек от HTML5 до различных резервных вариантов и некоторые полезные функции, упрощающие этот процесс. В зависимости от ваших потребностей и требований вы можете рассмотреть простую реализацию или любой из этих плагинов.

person 404    schedule 25.08.2014

Этот подключаемый модуль jQuery для загрузки файла AJAX загружает файл где-то и передает ответ на обратный вызов, ничего больше.

  • Это не зависит от конкретного HTML, просто дайте ему <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');
  }
});
person Jordan Feldstein    schedule 29.07.2011

Я использовал приведенный ниже сценарий для загрузки изображений, которые, как оказалось, работают нормально.

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.

person Techie    schedule 25.01.2013

Вы можете легко сделать это на обычном JavaScript. Вот отрывок из моего текущего проекта:

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);
person mpen    schedule 17.02.2013

Вы можете просто загрузить файл с помощью 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) {
                // ...
            }
       });
    }));
});
person Zayn Ali    schedule 08.08.2014

Самый простой и надежный способ, которым я делал это в прошлом, - просто настроить таргетинг на скрытый тег iFrame в вашей форме - тогда он будет отправлен в iframe без перезагрузки страницы.

Это если вы не хотите использовать плагин, JavaScript или любые другие формы «магии», кроме HTML. Конечно, вы можете комбинировать это с JavaScript или с чем-то еще ...

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

Вы также можете прочитать содержимое iframe onLoad на предмет ошибок сервера или успешных ответов, а затем вывести его пользователю.

Chrome, iFrames и onLoad

-note- вам нужно продолжать читать, только если вам интересно, как настроить блокировщик пользовательского интерфейса при загрузке / скачивании

В настоящее время Chrome не запускает событие onLoad для iframe, когда он используется для передачи файлов. Firefox, IE и Edge запускают событие onload для передачи файлов.

Единственное решение, которое я нашел для Chrome, - это использование cookie.

Для этого в основном при запуске загрузки / выгрузки:

  • [Клиентская сторона] Начните интервал, чтобы проверить наличие файла cookie.
  • [На стороне сервера] Делайте все, что вам нужно, с данными файла
  • [На стороне сервера] Установить cookie для интервала на стороне клиента
  • [Сторона клиента] Interval видит файл cookie и использует его как событие onLoad. Например, вы можете запустить блокировщик пользовательского интерфейса, а затем onLoad (или при создании файла cookie) удалить блокировщик пользовательского интерфейса.

Использование cookie для этого некрасиво, но работает.

Я сделал плагин jQuery для решения этой проблемы для Chrome при загрузке, вы можете найти здесь

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

Тот же основной принцип применим и к загрузке.

Чтобы использовать загрузчик (очевидно, включая JS)

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

А на стороне сервера, непосредственно перед передачей данных файла, создайте cookie

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

Плагин увидит файл cookie, а затем вызовет обратный вызов onComplete.

person ArtisticPhoenix    schedule 26.06.2014

Я написал об этом в Среда Rails. Это всего лишь около пяти строк JavaScript, если вы используете легкий плагин jQuery-form.

Задача состоит в том, чтобы заставить загрузку AJAX работать, поскольку стандартный remote_form_for не понимает отправку многостраничной формы. Он не будет отправлять данные файла, которые Rails ищет обратно с запросом AJAX.

Вот где в игру вступает плагин jQuery-form.

Вот код Rails для этого:

<% remote_form_for(:image_form, 
                   :url => { :controller => "blogs", :action => :create_asset }, 
                   :html => { :method => :post, 
                              :id => 'uploadForm', :multipart => true }) 
                                                                        do |f| %>
 Upload a file: <%= f.file_field :uploaded_data %>
<% end %>

Вот связанный код JavaScript:

$('#uploadForm input').change(function(){
 $(this).parent().ajaxSubmit({
  beforeSubmit: function(a,f,o) {
   o.dataType = 'json';
  },
  complete: function(XMLHttpRequest, textStatus) {
   // XMLHttpRequest.responseText will contain the URL of the uploaded image.
   // Put it in an image element you create, or do with it what you will.
   // For example, if you have an image elemtn with id "my_image", then
   //  $('#my_image').attr('src', XMLHttpRequest.responseText);
   // Will set that image tag to display the uploaded image.
  },
 });
});

И вот действие контроллера Rails, довольно ванильное:

 @image = Image.new(params[:image_form])
 @image.save
 render :text => @image.public_filename

Я использую это в течение последних нескольких недель с Bloggity, и это сработало как чемпион.

person wbharding    schedule 13.08.2009

Другой вариант - Simple Ajax Uploader:

https://github.com/LPology/Simple-Ajax-Uploader

  • Кроссбраузерность - работает в IE7 +, Firefox, Chrome, Safari, Opera
  • Поддерживает несколько одновременных загрузок - даже в браузерах, отличных от HTML5.
  • Без flash или внешнего CSS - всего один файл Javascript размером 5 КБ
  • Дополнительная встроенная поддержка полностью кроссбраузерных индикаторов выполнения (с использованием расширения PHP APC)
  • Гибкость и широкие возможности настройки - используйте любой элемент в качестве кнопки загрузки, создавайте собственные индикаторы прогресса
  • Формы не требуются, просто укажите элемент, который будет служить кнопкой загрузки.
  • Лицензия MIT - бесплатно для использования в коммерческом проекте

Пример использования:

var uploader = new ss.SimpleUpload({
    button: $('#uploadBtn'), // upload button
    url: '/uploadhandler', // URL of server-side upload handler
    name: 'userfile', // parameter name of the uploaded file
    onSubmit: function() {
        this.setProgressBar( $('#progressBar') ); // designate elem as our progress bar
    },
    onComplete: function(file, response) {
        // do whatever after upload is finished
    }
});
person user1091949    schedule 26.06.2013

Решение, которое я нашел, заключалось в том, чтобы <form> нацелился на скрытый iFrame. Затем iFrame может запустить JS, чтобы показать пользователю, что он завершен (при загрузке страницы).

person Darryl Hein    schedule 18.10.2008

jQuery Uploadify - еще один хороший плагин, который я использовал раньше для загрузки файлов. Код JavaScript очень прост: код. Однако новая версия не работает в 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) {
        // ...
    }
});

Я много искал и пришел к другому решению для загрузки файлов без каких-либо плагинов и только с ajax. Решение выглядит следующим образом:

$(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);
}
person farnoush resa    schedule 16.06.2013

Вот еще одно решение, как загрузить файл (без плагина)

Использование простых Javascripts и AJAX (с индикатором выполнения)

HTML-часть

<form id="upload_form" enctype="multipart/form-data" method="post">
    <input type="file" name="file1" id="file1"><br>
    <input type="button" value="Upload File" onclick="uploadFile()">
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
    <h3 id="status"></h3>
    <p id="loaded_n_total"></p>
</form>

Часть JS

function _(el){
    return document.getElementById(el);
}
function uploadFile(){
    var file = _("file1").files[0];
    // alert(file.name+" | "+file.size+" | "+file.type);
    var formdata = new FormData();
    formdata.append("file1", file);
    var ajax = new XMLHttpRequest();
    ajax.upload.addEventListener("progress", progressHandler, false);
    ajax.addEventListener("load", completeHandler, false);
    ajax.addEventListener("error", errorHandler, false);
    ajax.addEventListener("abort", abortHandler, false);
    ajax.open("POST", "file_upload_parser.php");
    ajax.send(formdata);
}
function progressHandler(event){
    _("loaded_n_total").innerHTML = "Uploaded "+event.loaded+" bytes of "+event.total;
    var percent = (event.loaded / event.total) * 100;
    _("progressBar").value = Math.round(percent);
    _("status").innerHTML = Math.round(percent)+"% uploaded... please wait";
}
function completeHandler(event){
    _("status").innerHTML = event.target.responseText;
    _("progressBar").value = 0;
}
function errorHandler(event){
    _("status").innerHTML = "Upload Failed";
}
function abortHandler(event){
    _("status").innerHTML = "Upload Aborted";
}

Часть PHP

<?php
$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "test_uploads/$fileName")){ // assuming the directory name 'test_uploads'
    echo "$fileName upload is complete";
} else {
    echo "move_uploaded_file function failed";
}
?>

Вот ПРИМЕР приложения

person Siddhartha Chowdhury    schedule 30.03.2016

var formData=new FormData();
formData.append("fieldname","value");
formData.append("image",$('[name="filename"]')[0].files[0]);

$.ajax({
    url:"page.php",
    data:formData,
    type: 'POST',
    dataType:"JSON",
    cache: false,
    contentType: false,
    processData: false,
    success:function(data){ }
});

Вы можете использовать данные формы для публикации всех ваших значений, включая изображения.

person Vivek Aasaithambi    schedule 28.07.2015

Современный подход без Jquery заключается в использовании FileList, который вы получаете обратно от <input type="file">, когда пользователь выбирает файл (ы), а затем использует Fetch, чтобы опубликовать список файлов, обернутый вокруг FormData. объект.

// The input DOM element // <input type="file">
const inputElement = document.querySelector('input[type=file]');

// Listen for a file submit from user
inputElement.addEventListener('change', () => {
    const data = new FormData();
    data.append('file', inputElement.files[0]);
    data.append('imageName', 'flower');

    // You can then post it to your server.
    // Fetch can accept an object of type FormData on its  body
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});
person Alister    schedule 17.08.2018

Чтобы загрузить файл асинхронно с помощью JQuery, выполните следующие действия:

шаг 1. В вашем проекте откройте диспетчер Nuget и добавьте пакет (jquery fileupload (вам нужно только написать его в поле поиска, он появится и установит его.)) URL: https://github.com/blueimp/jQuery-File-Upload

шаг 2 Добавьте ниже скрипты в файлы HTML, которые уже добавлены в проект, запустив указанный выше пакет:

jquery.ui.widget.js

jquery.iframe-transport.js

jquery.fileupload.js

шаг 3 Напишите элемент управления загрузкой файлов в соответствии с приведенным ниже кодом:

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

шаг 4 напишите метод js как uploadFile, как показано ниже:

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

шаг 5. Загрузите готовый файл элемента вызова функции, чтобы начать процесс, как показано ниже:

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

});

шаг 6 Напишите контроллер MVC и действие, как показано ниже:

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


        }

    }
person ashish    schedule 23.06.2014

Вы можете увидеть решенное решение с помощью рабочей демонстрации здесь, который позволяет просматривать и отправлять файлы форм на сервер. В вашем случае вам необходимо использовать Ajax, чтобы упростить загрузку файлов на сервер. :

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

Отправляемые данные представляют собой данные формы. В jQuery используйте функцию отправки формы вместо нажатия кнопки, чтобы отправить файл формы, как показано ниже.

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

     });
   });
});

Подробнее подробности

person Daniel Nyamasyo    schedule 19.07.2016

Пример: если вы используете jQuery, вы можете легко загрузить файл. Это небольшой и мощный плагин jQuery, http://jquery.malsup.com/form/.

Пример

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

Надеюсь, это будет полезно

person MEAbid    schedule 14.10.2016

Вы можете использовать

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

Демо

person Amit    schedule 12.05.2014

Преобразуйте файл в формат base64 с помощью | HTML5 readAsDataURL () или какой-нибудь кодировщик base64. Скрипка здесь

var reader = new FileReader();

        reader.onload = function(readerEvt) {
            var binaryString = readerEvt.target.result;
            document.getElementById("base64textarea").value = btoa(binaryString);
        };

        reader.readAsBinaryString(file);

Затем получить:

window.open("data:application/octet-stream;base64," + base64);
person tnt-rox    schedule 23.06.2014

Вы можете передать дополнительные параметры вместе с именем файла при выполнении асинхронной загрузки с помощью XMLHttpRequest (без зависимости от flash и iframe). Добавьте значение дополнительного параметра с помощью FormData и отправьте запрос на загрузку.


var formData = new FormData();
formData.append('parameter1', 'value1');
formData.append('parameter2', 'value2'); 
formData.append('file', $('input[type=file]')[0].files[0]);

$.ajax({
    url: 'post back url',
    data: formData,
// other attributes of AJAX
});

Кроме того, загрузка файла пользовательского интерфейса JavaScript в Syncfusion предоставляет решение для этого сценария, просто используя аргумент события. документацию можно найти здесь и дополнительные сведения об этом элементе управления введите здесь, введите описание ссылки здесь

person Karthik Ravichandran    schedule 14.11.2018

Это мое решение.

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

и 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>

Контроллер

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}
person Erick Lanford Xenes    schedule 03.11.2015
comment
Похоже, вы подмешали в свой ответ какую-то основу. Вы должны, по крайней мере, указать, для какой структуры подходит ваш ответ. А еще лучше удалить все элементы фреймворка и представить только ответ на поставленный вопрос. - person Zero3; 19.12.2015
comment
так есть на самом деле фреймворк mvc под названием mvc? и он использует синтаксис csharpish? это жестоко. - person nonchip; 07.01.2016

Найдите здесь Обработка процесса загрузки файла, асинхронно: https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications

Образец по ссылке

<?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>
person Allende    schedule 08.07.2015

Вы можете использовать более новую Fetch API с помощью JavaScript. Нравится:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

Преимущество: Fetch API изначально поддерживается всеми современными браузерами, поэтому вам не нужно ничего импортировать. Также обратите внимание, что fetch () возвращает Promise который затем обрабатывается асинхронно с использованием .then(..code to handle response..).

person BlackBeard    schedule 21.05.2018

Используя HTML5 и JavaScript, асинхронная загрузка довольно проста, я создаю логику загрузки вместе с вашим html, это не полностью работает, поскольку ему нужен api, но продемонстрируйте, как это работает, если у вас есть конечная точка с именем /upload из корня вашего веб-сайта, этот код должен работать для вас:

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>

Также некоторая дополнительная информация о XMLHttpReques:

Объект XMLHttpRequest

Все современные браузеры поддерживают объект XMLHttpRequest. Объект XMLHttpRequest можно использовать для обмена данными с веб-сервером за кулисами. Это означает, что можно обновлять части веб-страницы без перезагрузки всей страницы.


Создайте объект XMLHttpRequest

Все современные браузеры (Chrome, Firefox, IE7 +, Edge, Safari, Opera) имеют встроенный объект XMLHttpRequest.

Синтаксис для создания объекта XMLHttpRequest:

переменная = новый XMLHttpRequest ();


Доступ через домены

По соображениям безопасности современные браузеры не разрешают доступ между доменами.

Это означает, что и веб-страница, и XML-файл, который она пытается загрузить, должны находиться на одном сервере.

Примеры на W3Schools открывают все файлы XML, расположенные в домене W3Schools.

Если вы хотите использовать приведенный выше пример на одной из ваших собственных веб-страниц, загружаемые XML-файлы должны находиться на вашем собственном сервере.

Для получения дополнительной информации вы можете продолжить чтение здесь ...

person Alireza    schedule 12.03.2018

Вы можете выполнять асинхронную загрузку нескольких файлов с помощью JavaScript или jQuery и без использования какого-либо плагина. Вы также можете показать в реальном времени прогресс загрузки файла в контроле выполнения. Я нашел 2 хороших ссылки -

  1. Загрузка нескольких файлов на основе веб-форм ASP.NET Функция с индикатором выполнения
  2. Загрузка нескольких файлов на основе ASP.NET MVC, выполненная в jQuery

Серверный язык - C #, но вы можете внести некоторые изменения, чтобы заставить его работать с другим языком, таким как PHP.

Загрузка файла ASP.NET Core MVC:

В представлении создать элемент управления загрузкой файла в html:

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

Теперь создайте метод действия в вашем контроллере:

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

Переменная hostingEnvironment имеет тип IHostingEnvironment, который может быть введен в контроллер с помощью внедрения зависимостей, например:

private IHostingEnvironment hostingEnvironment;
public MediaController(IHostingEnvironment environment)
{
    hostingEnvironment = environment;
}
person Joe Clinton    schedule 29.08.2018

Для PHP найдите https://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}
person Supun Kavinda    schedule 05.10.2018

Это старый вопрос, но до сих пор нет правильного ответа, поэтому:

Вы пробовали jQuery-File-Upload?

Вот пример из приведенной выше ссылки, который может решить вашу проблему:

$('#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);
        });
    } 
});
person lat94    schedule 21.02.2018

Вы также можете рассмотреть возможность использования чего-то вроде https://uppy.io.

Он выполняет загрузку файлов без перехода со страницы и предлагает несколько бонусов, таких как перетаскивание, возобновление загрузки в случае сбоев браузера / нестабильных сетей и импорт, например, из Instagram. Это открытый исходный код и не полагается на jQuery / React / Angular / Vue, но может использоваться вместе с ним. Отказ от ответственности: как его создатель я пристрастен;)

person kvz    schedule 21.12.2018

Пытаться

async function saveFile() 
{
    let formData = new FormData();           
    formData.append("file", file.files[0]);
    await fetch('addFile.do', {method: "POST", body: formData});    
    alert("Data Uploaded: ");
}
<span>File</span>
<input type="file" id="file" name="file" size="10"/>
<input type="button" value="Upload" onclick="saveFile()"/>

content-type='multipart/form-data' устанавливается браузером автоматически, имя файла также автоматически добавляется к параметру filename FormData (и может быть легко прочитано сервером). Вот более проработанный пример с обработкой ошибок и добавлением json

async function saveFile(inp) 
{
    let user = { name:'john', age:34 };
    let formData = new FormData();
    let photo = inp.files[0];      
         
    formData.append("photo", photo);
    formData.append("user", JSON.stringify(user));  
    
    try {
       let r = await fetch('/upload/image', {method: "POST", body: formData}); 
       console.log('HTTP response code:',r.status); 
       alert('success');
    } catch(e) {
       console.log('Huston we have problem...:', e);
    }
    
}
<input type="file" onchange="saveFile(this)" >
<br><br>
Before selecting the file Open chrome console > network tab to see the request details.
<br><br>
<small>Because in this example we send request to https://stacksnippets.net/upload/image the response code will be 404 ofcourse...</small>

person Kamil Kiełczewski    schedule 05.07.2019

Вы можете использовать следующий код.

async: false(true)
person Michael Wang    schedule 08.04.2019
comment
Вы можете уточнить свой ответ? Непонятно, где сделать это изменение. - person kabirbaidhya; 14.09.2020
comment
Вы можете добавить его в функцию вызова ajax - person Michael Wang; 16.09.2020
comment
Это недопустимый синтаксис и не отвечает на этот вопрос. - person Sebastian Simon; 05.03.2021

Что делать, если использовать обещания, которые используют ajax, и проверять, действителен ли файл и хорошо ли он сохранен в вашем бэкэнде, чтобы вы могли использовать некоторую анимацию впереди, пока пользователь перемещается по вашей странице.

Вы даже можете сделать его параллельную загрузку или стек с рекурсивным подходом.

person Diego Vinícius    schedule 28.02.2020