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

2561

Я хотел бы загрузить файл асинхронно с помощью 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 Form Plugin для загрузки файлов.

  • 0
    Существуют различные готовые плагины для загрузки файлов для jQuery. Загрузка такого рода хаков не доставляет удовольствия, поэтому людям нравится использовать готовые решения. Вот несколько примеров : - JQuery File Uploader - Плагин для загрузки нескольких файлов - Мини-загрузка нескольких файлов - Загрузка файлов jQuery Вы можете искать другие проекты в NPM (используя «jquery-plugin» в качестве ключевого слова) или в Github.
  • 72
    вы получаете только имя файла, потому что ваше имя файла var получает значение $ ('# file'), а не файл, который лежит на входе
Показать ещё 7 комментариев
Теги:
asynchronous
upload

33 ответа

2512

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

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

  • 0
    Как вернуть данные из файла, в который был отправлен файл?
  • 1
    @ Silver89, если вы хотите вернуть данные из серверного скрипта, который вы установили в настройке URL-адреса (в данном случае «upload.php»), ответом будет то, что вы напечатали или повторили в этом скрипте. Тогда вы можете делать все, что вы хотите с данными. Проверьте ajaxComplete и аналогичные функции в JQuery Docs
Показать ещё 35 комментариев
336

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

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

Здесь несколько:

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

234

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

Важное значение для понимания с помощью нового API HTML5 file заключается в том, что не поддерживался до 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. Они намного более гибки в том, что они могут делать со своими сообщениями...

  • 139
    Напомним, что теперь можно выполнять чистую загрузку файлов AJAX, если браузер поддерживает File API - developer.mozilla.org/en/using_files_from_web_applications
  • 33
    Если вам не нужна поддержка IE9. caniuse.com/fileapi
Показать ещё 4 комментария
103

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

$(document).ready(function() {
  $("#uploadbutton").jsupload({
    action: "addFile.do",
    onComplete: function(response){
      alert( "server response: " + response);
    }
  });
});
  • 0
    Он использует JSON - поэтому для старой версии PHP это будет невозможно.
  • 0
    Кажется, намного чище, чем Ajax File Upload, где мне нужно включить огромный кусок кода, чтобы использовать эту чертову штуку.
Показать ещё 10 комментариев
88

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


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

  • 1
    Да, вы можете POST в iframe и захватить файл там. У меня очень ограниченный опыт с этим, поэтому я не могу комментировать это.
  • 15
    Небольшое замечание: в последних версиях Chrome и Firefox это возможно, stackoverflow.com/questions/4856917/…
Показать ещё 1 комментарий
82

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

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

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

В этом случае вы можете предпочесть использовать плагин-оболочку, такой как 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 Plugin или jQuery File Upload, включают весь стек из HTML5 в различные резервные копии и некоторые полезные функции для облегчения процесса. В зависимости от ваших потребностей и требований вы можете рассмотреть голый вариант реализации или любой из этих плагинов.

  • 3
    На основании документации следует отметить одно: вы также должны отправить contentType: false . Когда я не отправил это с Chrome, тип содержимого формы был признан недействительным jQuery.
  • 0
    Хороший ответ. Несколько предложений по улучшению: Удалите части кода, не связанные с ответом, например, .done() и .fail() . Кроме того, пример без использования FormData и списка FormData / минусов был бы потрясающим.
Показать ещё 1 комментарий
79

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

  • Это не зависит от конкретного 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');
  }
});
  • 4
    Не работает с 1.9.1: |
  • 1
    @ user840250 jQuery 1.9.1?
61

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

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, чтобы показать загрузку анимации и ответ после завершения загрузки.

Лучше всего вы можете отправить дополнительные данные, такие как идентификаторы и т.д., с файлом при использовании этого script. Я упомянул его extra-data, как в script.

На уровне PHP это будет работать как обычная загрузка файла. дополнительные данные могут быть получены как данные $_POST.

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

  • 5
    -1 для использования jQuery и не использовать его селекторный движок и обработчики событий. addEventListener не является кросс-браузерным.
  • 3
    Потому что было бы бессмысленно добавлять отдельный ответ, который будет в основном основан на этом, с несколькими изменениями. Вместо этого этот ответ должен быть исправлен.
Показать ещё 3 комментария
53

Я столкнулся с несколькими действительно мощными jQuery файлами для загрузки файлов. Проверьте их:

45

Вы можете загрузить просто с помощью 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) {
                // ...
            }
       });
    }));
});
  • 0
    Какая библиотека jQuery мне нужна для запуска этого кода?
  • 1
    @RaydenBlack только jQuery.
Показать ещё 2 комментария
43

Вы можете легко это сделать в ванильном 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);
  • 3
    @Gary: Извините, я должен был опубликовать этот бит тоже. Я просто использовал новую функциональность перетаскивания в HTML5; Вы можете найти пример здесь: html5demos.com/file-api#view-source - просто нажмите «Просмотр источника». По сути, внутри события ondrop вы можете сделать var file = e.dataTransfer.files[0]
  • 0
    Возможно, вопрос был отредактирован с тех пор, но некоторые люди в открытой дискуссии, которую я открыл, считают, что ванильный ответ JS не по теме, если OP запрашивает решение jQuery (при условии, что оно существует), и такие ответы принадлежат отдельному вопросу.
Показать ещё 1 комментарий
39

Самый простой и самый надежный способ, который я делал в прошлом, - просто нацелить скрытый тег 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 для клиентского интервала
  • [Клиентская сторона] Интервал видит файл cookie и использует его как событие onLoad. Например, вы можете запустить блокиратор пользовательского интерфейса, а затем onLoad (или когда файл cookie сделан) вы удалите блокиратор пользовательского интерфейса.

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

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

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

  • 3
    Я люблю это. Если бы кто-то мог упомянуть потенциальные проблемы с этим блестящим решением. Я действительно не понимаю, почему люди пишут и используют эти неуклюжие библиотеки и плагины, когда есть решение.
  • 1
    Ну, я думаю, причина в том, чтобы показать некоторую информацию о прогрессе при загрузке.
31

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

  • 0
    Вот что делает форма jQuery: malsup.com/jquery/form
  • 1
    меня интересует этот ответ, у вас есть демоверсия, на которую вы можете сослаться?
30

Простая загрузка Ajax - это еще одна опция:

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

  • Кросс-браузер - работает в IE7 +, Firefox, Chrome, Safari, Opera
  • Поддержка нескольких одновременных загрузок - даже в браузерах, отличных от HTML5
  • Нет флеш-памяти или внешнего CSS - всего один файл Javascript 5Kb
  • Дополнительная встроенная поддержка полнопроходных баров (используя расширение 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
    }
});
  • 2
    Это, кажется, самое многообещающее на данный момент, вы приняли меня на IE7+ ! Попробуй это сейчас. Спасибо
30

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

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

То, в которое входит плагин jQuery-form.

Код Heres 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.
  },
 });
});

И heres действие контроллера Rails, симпатичная ваниль:

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

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

23

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

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

Использование простых 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";
}
?>

Здесь приложение ПРИМЕР

  • 0
    Не работает с IE9.
15
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){ }
});

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

  • 6
    Примечание: cache: false избыточно POST запросе POST поскольку POST никогда не кэшируется.
  • 0
    @ Vivek Aasaithambi, я получил эту ошибку: Ошибка TypeError: Argument 1 of FormData.constructor does not implement interface HTMLFormElement.
13

Чтобы загрузить файл асинхронно с помощью 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
                };


        }

    }
9

Преобразуйте файл в 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);
8

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

// The input DOM element
const inputElement = document.querySelector('input');

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

    // Post to server
    fetch('/uploadImage', {
        method: 'POST',
        body: data
    });
});
  • 0
    Видимо не поддерживается в IE
8

Пример. Если вы используете 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
  }
});

Я надеюсь, что было бы полезно

8

Вы можете увидеть решение с рабочей демонстрацией здесь, которая позволяет просматривать и отправлять файлы формы сервер. Для вашего случая вам необходимо использовать 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>

Представленные данные являются formdata. В 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");

     });
   });
});

Подробнее

8

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

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

Demo

6

Вы можете передать дополнительные параметры вместе с именем файла при выполнении асинхронной загрузки с использованием 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
});

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

6

Посмотрите, как обрабатывать процесс загрузки файла, асинхронно здесь: 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>
3

Используя HTML5 и JavaScript, загрузка async довольно проста, я создаю логику загрузки вместе с вашим 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:

variable = new XMLHttpRequest();


Доступ во всех доменах

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

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

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

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

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

3

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

<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)
{
    return Json(":)");
}
  • 2
    Вы, кажется, смешали какую-то структуру в свой ответ. Вы должны, по крайней мере, указать, для какой структуры ваш ответ пригоден для использования. А еще лучше, удалите все элементы фреймворка и представьте только ответ на поставленный вопрос.
  • 2
    так что на самом деле фреймворк MVC называется "MVC"? и он использует синтаксис csharpish? это жестоко
2

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

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

Серверный язык - С#, но вы можете внести некоторые изменения, чтобы он работал с другим языком, таким как 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;
}
  • 0
    Не могли бы вы указать суть решения в своем ответе, так как в противном случае оно может стать бесполезным, если связанный веб-сайт изменится или перейдет в автономный режим.
2

Вы можете использовать новый API Fetch с помощью 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));
}                               

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

1

Для 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 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()
        )
    ));
}
1

Это старый вопрос, но ответа на правильный ответ пока нет, так что:

Вы пытались загрузить jQuery-File-Upload?

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню