Как мога да качвам файлове асинхронно?

Бих искал да кача файл асинхронно, използвайки 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 за качване на файлове.

2695
03 окт. определени от Sergio del Amo 03 окт. 2008-10-03 13:22 '08 в 1:22 pm 2008-10-03 13:22
@ 33 отговора
  • 1
  • 2

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

 $(':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 в примерите не са налице във всеки браузър.

2393
06 янв. Отговорът е даден olanod 06 януари 2012-01-06 16:34 '12 в 16:34 ч. 2012-01-06 16:34

Има различни готови приставки за изтегляне на jQuery файлове.

Изпълнението на този тип хакове не е приятно преживяване, така че хората обичат да използват готови решения.

Ето няколко:

border=0

Можете да търсите повече проекти на НПМ (като използвате "jquery-plugin" като ключова дума) или на Github.

336
15 окт. Отговорът е даден Cheery 15 oct. 2008-10-15 13:35 '08 в 13:35 2008-10-15 13:35

2017 Update: тя все още зависи от браузърите, които използват демографските данни.

Важно е да разберете с помощта на новия HTML5 file API, че не е поддържан преди IE 10 . Ако конкретният пазар, към който насочвате, има по-висока от средната стойност за предходни версии на Windows, може да нямате достъп до нея.

От 2017 г. около 5% от браузърите са една от IE 6, 7, 8 или 9. Ако отиваш в голяма корпорация (например, това е B2B инструмент или нещо, което доставяш за обучение), този брой може да е ракета. Само преди няколко месеца - през 2016 г. - имах работа с компания, която използва IE8 за повече от 60% от своите машини.

Така че, преди да направите нещо: проверете дали браузърът ви се използва от потребителя . Ако не направите това, ще научите бърз и болезнен урок, защо „работата за мен“ не е достатъчно добра за доставяне на клиент.

Това е последвано от моя отговор от 2008 г.


Въпреки това, съществуват надеждни методи за качване на файлове без JS. Можете да създадете вградена рамка на страница (която скриете с CSS) и след това да насочите формата си към публикуване във вградена рамка. На главната страница не е нужно да се движите.

Това е "истинска" публикация, така че тя не е напълно интерактивна. Ако имате нужда от статус, трябва да имате сървър, за да го обработите. Това зависи от вашия сървър. ASP.NET има по-удобни механизми. PHP plain не работи, но можете да използвате Perl или Apache модификации, за да го заобиколите.

Ако имате нужда от множество файлове за изтегляне, най-добре е да правите всеки един файл поотделно (за да преодолеете максималните ограничения за изтегляне на файлове). Изпратете първия формуляр в рамката, прегледайте неговия напредък, използвайте по-горе и когато е завършен, поставете втората форма в iframe и т.н.

Или използвайте решение Java / Flash. Те са много по-гъвкави в това, което могат да правят с посланията си ...

246
03 окт. Отговорът е даден Oli 03 oct. 2008-10-03 13:41 '08 в 13:41 2008-10-03 13:41

За тази цел препоръчвам да използвате приставката за фино качване . Вашият код на JavaScript ще бъде:

 $(document).ready(function() { $("#uploadbutton").jsupload({ action: "addFile.do", onComplete: function(response){ alert( "server response: " + response); } }); }); 
108
21 нояб. отговорът е даден на pixxaar 21 ноември. 2008-11-21 19:38 '08 в 19:38 ч. 2008-11-21 19:38

Забележка. Този отговор е остарял, вече можете да качвате файлове с помощта на XHR.


Не можете да качвате файлове с помощта на XMLHttpRequest (Ajax). Можете да симулирате ефекта с помощта на iframe или flash. Голям плъгин за jQuery Form, който изпраща вашите файлове чрез iframe, за да получи ефекта.

92
03 окт. отговор, даден от Матиас на 03 октомври 2008-10-03 13:36 '08 в 13:36 2008-10-03 13:36

Този 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'); } }); 
83
29 июля '11 в 3:34 2011-07-29 03:34 отговорът е даден от Йордан Фелдщайн на 29 юли 2009 г. в 3:34 ч. 2011-07-29 03:34

Обобщава се за бъдещите читатели.

Изтеглете асинхронен файл

От 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.

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

82
25 авг. отговорът е даден 404 25 авг. 2014-08-25 17:17 '14 в 17:17 2014-08-25 17:17

Използвах скрипта по-долу за качване на снимки, които работят добре.

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.

59
25 янв. Отговор, даден от Techie 25 януари 2013-01-25 14:03 '13 в 14:03 2013-01-25 14:03

Срещнах няколко много мощни JQuery файлове за изтегляне на файлове. Проверете ги:

55
08 апр. Отговорът е даден Христо 08 апр. 2011-04-08 19:43 '11 в 19:43 2011-04-08 19: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); 
43
17 февр. отговорът е даден mpen 17 feb . 2013-02-17 12:34 '13 в 12:34 ч. 2013-02-17 12:34

Можете да я заредите само с помощта на jQuery .ajax() .

HTML:

 .progress { display: none; } 

JavaScript:

43
08 авг. отговорът е даден от Зайн Али 08 август. 2014-08-08 05:59 '14 в 5:59 ч. 2014-08-08 05:59

Най-лесният и най-надеждният начин, който направих в миналото, е просто да насочите скрития маркер на 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

- Забележка - само трябва да прочетете, ако се чудите как да настроите заключване на потребителския интерфейс при зареждане / зареждане

Понастоящем Chrome не задейства събитие onLoad за вградена рамка, когато се използва за прехвърляне на файлове. Firefox, IE и Edge задействат събитието onload за прехвърляне на файлове.

Единственото решение, което намерих за Chrome, е да използва бисквитка.

За това предимно при зареждане / сваляне:

  • [Клиентска страна] Започнете интервала за търсене на бисквитки
  • [Сървърна страна] Направете всичко, което ви трябва, с файлови данни
  • [Server Side] Задайте бисквитка за клиентския интервал
  • [Клиентска страна] Интервалът вижда бисквитката и го използва като събитие onLoad. Например, можете да стартирате блокер на потребителския интерфейс, а след това onLoad (или когато бисквитката е завършена) премахвате блокера на потребителския интерфейс.

Използването на бисквитка за това е грозно, но работи.

Създадох jQuery плъгин, за да разреша този проблем за Chrome при зареждане, можете да намерите тук

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

Същият основен принцип важи и за изтеглянето.

За да използвате bootloader (включително 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'); }); 

А на сървърната страна, преди да предаде данните на файла, създайте бисквитка

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

Приставката ще види „бисквитката“ и след това ще активира onComplete връзка onComplete .

39
26 июня '14 в 7:43 2014-06-26 07:43 Отговорът е даден на ArtisticPhoenix 26 юни '14 в 7:43 2014-06-26 07:43

Решението, което намерих, беше, че целта на <form> е скритото iFrame. След това iFrame може да изпълнява JS за показване на потребителя, който го е завършил (когато се зарежда страницата).

32
18 окт. отговор, даден от Darryl Hein Oct 18. 2008-10-18 22:30 '08 в 22:30 часа 2008-10-18 22:30

Написах това в среда на Rails . Това са само пет реда javascript, ако използвате приставката за формуляри jQuery.

Предизвикателството е, че AJAX зареждането работи, защото стандартният remote_form_for не разбира многокомпонентната форма на изгледа. Той няма да изпраща файлове. Rails търси AJAX заявка.

Това, което включва плъгина за jQuery-форма.

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

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

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

Използвах го през последните няколко седмици с Bloggity и той работи като шампион.

31
14 авг. Отговорът е даден твърд 14 август. 2009-08-14 01:44 '09 в 1:44 2009-08-14 01:44

Простото зареждане на Ajax е друга опция:

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

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

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

30
26 июня '13 в 4:12 2013-06-26 04:12 отговорът е даден от user1091949 26 юни '13 в 4:12 2013-06-26 04:12

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); } 
22
16 июня '13 в 12:49 2013-06-16 12:49 отговорът е даден от farnoush resa 16 юни '13 в 12:49 2013-06-16 12:49

Това е просто друго решение, как да качите файл ( без приставката )

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

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

21
30 марта '16 в 19:48 2016-03-30 19:48 отговорът е даден на Siddhartha Chowdhury 30 март '16 в 19:48 2016-03-30 19:48
 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){ } }); 

Можете да използвате данните за формуляри, за да публикувате всичките си стойности, включително изображения.

15
28 июля '15 в 16:39 2015-07-28 16:39 отговорът е даден от Vivek Aasaithambi 28 юли '15 в 16:39 2015-07-28 16:39

За да изтеглите файл асинхронно с помощта на 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 }; } } 
13
23 июня '14 в 11:18 2014-06-23 11:18 отговорът се дава на аш 23 юни, 14 в 11:18 2014-06-23 11:18

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