Multipart / formdata siuntimas su jQuery.ajax

Turiu problemą siunčiant failą į serverio pusės PHP scenarijų naudojant jQuery ajax funkciją. Galite gauti failų sąrašą su $('#fileinput').attr('files') , bet kaip galite siųsti šiuos duomenis į serverį? Naudojant failo įvestį, gautas masyvas ( $_POST ) php-script serveryje yra 0 ( NULL ).

Žinau, kad tai įmanoma (nors iki šiol neradau jokių jQuery sprendimų, tik „Prototye“ kodas ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) ).

Tai atrodo gana nauja, todėl nepaminėkite, kad failo atsisiuntimas nebūtų įmanomas per XHR / Ajax, nes jis tikrai veikia.

Man reikia, kad „Safari 5“, „FF“ ir „Chrome“ funkcionalumas būtų gražus, bet ne būtinas.

Dabar mano kodas yra:

 $.ajax({ url: 'php/upload.php', data: $('#file').attr('files'), cache: false, contentType: 'multipart/form-data', processData: false, type: 'POST', success: function(data){ alert(data); } }); 
451
22 марта '11 в 16:52 2011-03-22 16:52 „zoku“ yra nustatytas kovo 22 d ., „11, 16:52 2011-03-22 16:52
@ 12 atsakymų

Pradedant nuo „Safari 5 / Firefox 4“, paprasčiausias būdas naudoti „ FormData klasę FormData :

 var data = new FormData(); jQuery.each(jQuery('#file')[0].files, function(i, file) { data.append('file-'+i, file); }); 

Taigi dabar turite „ FormData objektą, kurį galima siųsti su XMLHttpRequest.

 jQuery.ajax({ url: 'php/upload.php', data: data, cache: false, contentType: false, processData: false, method: 'POST', type: 'POST', // For jQuery < 1.9 success: function(data){ alert(data); } }); 

Turi būti nustatytas parametro contentType parametras false , priverčiant jQuery neįtraukti Content-Type antraštės jums, kitaip šios linijos ribos nebus. Be to, turite palikti processData vėliavą false, kitaip jQuery bandys konvertuoti jūsų FormData į eilutę, kuri nebus sėkminga.

Dabar galite gauti failą PHP naudojant:

 $_FILES['file-0'] 

(Yra tik vienas failas, file-0 , jei įvesdami failą nenurodėte multiple atributų, tokiu atveju skaičiai kiekvienam failui padidės.)

FormData“ emuliacijos naudojimas senesnėms naršyklėms

 var opts = { url: 'php/upload.php', data: data, cache: false, contentType: false, processData: false, method: 'POST', type: 'POST', // For jQuery < 1.9 success: function(data){ alert(data); } }; if(data.fake) { // Make sure no text encoding stuff is done by xhr opts.xhr = function() { var xhr = jQuery.ajaxSettings.xhr(); xhr.send = xhr.sendAsBinary; return xhr; } opts.contentType = "multipart/form-data; boundary="+data.boundary; opts.data = data.toString(); } jQuery.ajax(opts); 

Sukurkite formų duomenis iš esamos formos

Vietoj to, kad rankiniu būdu kartotumėte failus, FormData objektas taip pat gali būti sukurtas su esamo formos objekto turiniu:

 var data = new FormData(jQuery('form')[0]); 

Vietoj skaitiklio naudokite savo PHP masyvą

Tiesiog pavadinkite savo failo elementus ir paleiskite pavadinimą skliausteliuose:

 jQuery.each(jQuery('#file')[0].files, function(i, file) { data.append('file[]', file); }); 

$_FILES['file'] bus masyvas, kuriame yra laukai failams atsisiųsti kiekvienam $_FILES['file'] failui. Tai tikrai rekomenduoju savo pradiniame sprendime, nes lengviau ją surūšiuoti.

748
12 мая '11 в 12:36 2011-05-12 12:36 atsakymą pateikė Raphael Schweikert gegužės 12 d. 11 val. 12:36 2011-05-12 12:36

Aš ką tik sukūriau šią funkciją, remdamasi kai kuria informacija, kurią perskaičiau.

Naudokite jį naudodami .serialize() , vietoj tiesiog įdėkite .serializefiles(); .
Čia atlikite bandymus.

border=0
 //USAGE: $("#form").serializefiles(); (function($) { $.fn.serializefiles = function() { var obj = $(this);  var formData = new FormData(); $.each($(obj).find("input[type='file']"), function(i, tag) { $.each($(tag)[0].files, function(i, file) { formData.append(tag.name, file); }); }); var params = $(obj).serializeArray(); $.each(params, function (i, val) { formData.append(val.name, val.value); }); return formData; }; })(jQuery); 
41
14 сент. Atsakymas pateikiamas evandro777 14 sep . 2012-09-14 17:33 '12, 17:33, 2012-09-14 17:33

Tiesiog norėjau šiek tiek pridėti Rafaelo puikų atsakymą. Čia, kaip padaryti PHP sukurti tuos pačius $_FILES , nepriklausomai nuo to, ar naudojate „JavaScript“ siųsti.

HTML forma:

 Array ( [media] => Array ( [name] => Array ( [0] => Galata_Tower.jpg [1] => 518f.jpg ) [type] => Array ( [0] => image/jpeg [1] => image/jpeg ) [tmp_name] => Array ( [0] => /tmp/phpIQaOYo [1] => /tmp/phpJQaOYo ) [error] => Array ( [0] => 0 [1] => 0 ) [size] => Array ( [0] => 258004 [1] => 127884 ) ) ) 

Jei darote pažangą, naudokite „Raphael JS“ failams siųsti ...

 Array ( [0] => Array ( [name] => Galata_Tower.jpg [type] => image/jpeg [tmp_name] => /tmp/phpAQaOYo [error] => 0 [size] => 258004 ) [1] => Array ( [name] => 518f.jpg [type] => image/jpeg [tmp_name] => /tmp/phpBQaOYo [error] => 0 [size] => 127884 ) ) 

Tai yra geras masyvas, ir kai kurie žmonės konvertuoja $_FILES į, bet manau, kad naudinga dirbti su tais pačiais $_FILES , neatsižvelgiant į tai, ar „JavaScript“ buvo naudojama siuntimui. Taigi čia yra keletas nedidelių JS pakeitimų:

39
10 янв. atsakymą pateikė ajmicek 10 sausis 2012-01-10 03:56 '12 at 3:56 2012-01-10 03:56

Pažvelkite į mano kodą, tai mano darbas.

 $( '#formId' ) .submit( function( e ) { $.ajax( { url: 'FormSubmitUrl', type: 'POST', data: new FormData( this ), processData: false, contentType: false } ); e.preventDefault(); } ); 
33
30 авг. Atsakymą pateikė Asad Malik 30 rug. 2014-08-30 09:49 '14 ne 9:49 2014-08-30 09:49

Jei jūsų forma yra apibrėžta HTML, lengviau perduoti formą konstruktoriui nei kartoti ir pridėti vaizdų.

 $('#my-form').submit( function(e) { e.preventDefault(); var data = new FormData(this); // <-- 'this' is your form element $.ajax({ url: '/my_URL/', data: data, cache: false, contentType: false, processData: false, type: 'POST', success: function(data){ ... 
19
02 июня '14 в 20:43 2014-06-02 20:43 atsakymą pateikė Devin Venable birželio 14 d. 14 d. 20:43 2014-06-02 20:43

„Devin Venable“ atsakymas buvo panašus į tai, ko norėjau, bet norėjau, kad jis dirbtų su keliomis formomis ir naudodamas jau nurodytą veiksmą, kad kiekviena byla būtų tinkama.

Taip pat norėjau naudoti jQuery on () metodą, kad būtų išvengta .ready ().

Tai paskatino mane: (pakeisti formąSelektorius su jQuery selektoriumi)

 $(document).on('submit', formSelecter, function( e ) { e.preventDefault(); $.ajax( { url: $(this).attr('action'), type: 'POST', data: new FormData( this ), processData: false, contentType: false }).done(function( data ) { //do stuff with the data you got back. }); }); 
4
15 июня '16 в 19:54 2016-06-15 19:54 Atsakymą pateikė Karl Henselin birželio 16 d. 16:54 2016-06-15 19:54

FormData klasė veikia, bet iOS Safari (bent jau „iPhone“) negalėjau naudoti Rafael Schweikert sprendimo.

„Mozilla Dev“ yra puikus puslapis, kai tvarkomi „FormData“ objektai .

Taigi pridėkite tuščią formą savo puslapyje, nurodydami enctype:

 <form enctype="multipart/form-data" method="post" name="fileinfo" id="fileinfo"></form> 

Tada sukurkite „FormData“ objektą, pvz .:

 var data = new FormData($("#fileinfo")); 

ir veikia kaip Raphael kodas .

1
22 февр. atsakymas duotas topkara vasaris 22 2013-02-22 03:24 '13, 3:24, 2013-02-22 03:24

Viena iš mano problemų, su kuriomis susidūriau šiandien, manau, yra atkreipti dėmesį į šią problemą: jei peradresuojamas „ajax“ skambučio URL, turinio tipo antraštė „multipart / form-data“ gali būti prarasta.

Pvz., Atsiunčiau pranešimą http://server.com/context?param=x

„Chrome“ skirtuko „Tinklas“ skirtuko lape pamačiau teisingą šio puslapio daugelio puslapių antraštę, bet tada nukreipiau 302 į http://server.com/context/?param=x (atkreipkite dėmesį į šoną po konteksto)

Peradresavimo metu buvo prarasta kelių dalių antraštė. Užtikrinkite, kad prašymai nebūtų peradresuoti, jei šie sprendimai neveiks.

0
18 марта '16 в 1:07 2016-03-18 01:07 atsakymą pateikė Jamesas kovo 18 d. 16 d. 1:07 2016-03-18 01:07

Senesnės IE versijos nepalaiko „FormData“ (visas „FormData“ naršyklės palaikymo sąrašas pateikiamas šiuo adresu: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).

Arba galite naudoti „jquery“ papildinį (pvz., „ Http://malsup.com/jquery/form/#code-samples“ ), arba galite naudoti „IFrame“ sprendimą norėdami išsiųsti kelių puslapių formą „ajax“: https: // kūrėjas. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

0
08 февр. atsakymas pateikiamas sudip 08 vasaris. 2018-02-08 13:42 '18, 13:42 pm 2018-02-08 13:42

Visi pirmiau minėti sprendimai atrodo gražūs ir elegantiški, tačiau „FormData“ () objektas neprognozuoja jokio parametro, bet po jo sukūrimo naudoja priedą (), kaip tai, kas parašyta aukščiau:

formData.append (val.name, val.value);

0
08 марта '18 в 16:47 2018-03-08 16:47 atsakymas pateikiamas szatti1489 kovo 8 d. 18 val. 16:47 2018-03-08 16:47
  • Gaukite formos objektą naudodami jquery-> $ („# id“) [0]
  • data = new FormData ($ ("# id") [0]);
  • gerai, duomenys yra jūsų pageidavimai.
-1
18 июля '13 в 12:54 2013-07-18 12:54 atsakymą pateikė vartotojo1909226 liepos 18 d., 13 val. 12:54 2013-07-18 12:54

Kaip alternatyvą AJAX, galite pridėti paslėptą iframe savo dokumentą, nukopijuokite savo formą ir paskelbti ją (taip, kad matomame puslapyje nebūtų peradresavimo). Manau, kad po to galite pašalinti iframe.

(HTML ir JS yra įsilaužėlių technologijos, o ne programuotojai. Turėsite išeiti iš šios ... Tai buvo ... Dievas žino, kiek metų korekcijos ir „JS“ ir „HTML“ kūrimas, ir jūs vis tiek negalite to padaryti taip paprasta, nenaudojant išorinių bibliotekų. Aš pavargau nuo to (žinau apie HTML5, tai nepakanka ir nėra plačiai palaikoma))

-11
04 дек. atsakymas, kurį pateikė user2173353 04 Dec. 2013-12-04 17:48 '13, 17:48 PM 2013-12-04 17:48