Mam problem z wysłaniem pliku na serwerowy skrypt PHP przy użyciu funkcji ajax w jQuery. Możliwe jest pobranie listy plików, $('#fileinput').attr('files')
ale jak można wysłać te dane na serwer? Wynikowa tablica ( $_POST
) po stronie skryptu php to 0 (NULL
) podczas korzystania z wejścia pliku.
Wiem, że jest to możliwe (chociaż do tej pory nie znalazłem żadnych rozwiązań jQuery, tylko kod Prototye ( http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html ) ).
Wydaje się to być stosunkowo nowe, więc proszę nie wspominać, że przesyłanie plików byłoby niemożliwe przez XHR / Ajax, ponieważ zdecydowanie działa.
Potrzebuję funkcjonalności w Safari 5, FF i Chrome byłyby fajne, ale nie są niezbędne.
Mój kod na razie to:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
$(':file')
aby wybrać wszystkie pliki wejściowe. To tylko trochę prostsze.Odpowiedzi:
Począwszy od Safari 5 / Firefox 4 najłatwiej jest użyć
FormData
klasy:Teraz masz
FormData
obiekt gotowy do wysłania wraz z XMLHttpRequest.Konieczne jest ustawienie tej
contentType
opcjifalse
, zmuszając jQuery, aby nie dodawałContent-Type
nagłówka, w przeciwnym razie nie będzie w nim ciągu granicznego. Musisz także pozostawićprocessData
flagę ustawioną na false, w przeciwnym razie jQuery spróbuje przekonwertować twójFormData
ciąg znaków, co się nie powiedzie.Możesz teraz pobrać plik w PHP, używając:
(Jest tylko jeden plik,
file-0
chyba że określiłeśmultiple
atrybut na wejściu pliku, w takim przypadku liczby będą rosły z każdym plikiem).Korzystanie z emulacji FormData dla starszych przeglądarek
Utwórz FormData z istniejącego formularza
Zamiast ręcznie iterować pliki, obiekt FormData można również utworzyć z zawartością istniejącego obiektu formularza:
Użyj natywnej tablicy PHP zamiast licznika
Wystarczy nazwać elementy pliku tak samo i zakończyć nazwę w nawiasach:
$_FILES['file']
będzie wówczas tablicą zawierającą pola przesyłania plików dla każdego przesłanego pliku. Tak naprawdę polecam to w stosunku do mojego początkowego rozwiązania, ponieważ łatwiej jest iterować.źródło
data.fake
i ustawićcontentType
właściwość ręcznie, a także zastąpić xhr, aby użyćsendAsBinary()
.jQuery
ani zFormData
klasy, a pytasz mnie w kontekście pytania dotyczącego jQuery i odpowiedzi dotyczącej używania FormData? Przykro mi, ale nie sądzę, żebym mógł ci tam pomóc ...application/x-www-form-urlencoded
. Czy istnieje sposób, aby użyćmultipart/form-data
zamiast tego?multipart/form-data
. Korzystanieapplication/x-www-form-urlencoded
nie działałoby.Chciałem tylko dodać trochę do świetnej odpowiedzi Raphaela. Oto jak zmusić PHP do wyprodukowania tego samego
$_FILES
, niezależnie od tego, czy używasz JavaScript do przesyłania.Formularz HTML:
PHP produkuje to
$_FILES
, gdy przesłane bez JavaScript:Jeśli robisz stopniowe ulepszanie, używając JS Raphaela do przesyłania plików ...
... tak
$_FILES
wygląda tablica PHP po użyciu tego JavaScript do przesłania:To fajna tablica i faktycznie to, w co niektórzy ludzie przekształcają
$_FILES
, ale uważam, że warto pracować z tym samym$_FILES
, bez względu na to, czy JavaScript był używany do przesyłania. Oto kilka drobnych zmian w JS:(Edycja z 14 kwietnia 2017 r .: usunąłem element formularza z konstruktora FormData () - to naprawiło ten kod w Safari).
Ten kod ma dwie rzeczy.
input
atrybut name automatycznie, dzięki czemu HTML bardziej linkujących. Teraz, o ileform
klasa putImages, wszystko inne jest załatwiane automatycznie. Oznacza to, żeinput
nie trzeba mieć żadnej specjalnej nazwy.Dzięki tym zmianom przesyłanie za pomocą JavaScript tworzy teraz dokładnie tę samą
$_FILES
tablicę, co przesyłanie za pomocą prostego HTML.źródło
Spójrz na mój kod, robi to za mnie
źródło
Właśnie zbudowałem tę funkcję na podstawie przeczytanych informacji.
.serialize()
Zamiast tego po prostu użyj.serializefiles();
.Pracuję tutaj w moich testach.
źródło
var data = $("#avatar-form").serializefiles();
wysyłaniem tego za pomocą parametru danych ajax i analizowanie ekspresowym formidable:form.parse(req, function(err, fields, files){
dziękuję za ten fragment kodu :)Jeśli formularz jest zdefiniowany w kodzie HTML, łatwiej jest przekazać formularz do konstruktora niż iterować i dodawać obrazy.
źródło
Odpowiedź Devina Venable'a była zbliżona do tego, czego chciałem, ale chciałem takiego, który będzie działał na wielu formularzach i używał akcji już określonej w formularzu, aby każdy plik trafił we właściwe miejsce.
Chciałem również użyć metody on () jQuery, aby uniknąć używania .ready ().
Doprowadziło mnie to do tego: (zastąp formSelector swoim selektorem jQuery)
źródło
W dzisiejszych czasach nie potrzebujesz nawet jQuery :) pobierania tabeli wsparcia API
źródło
fetch
zobacz zgodność: developer.mozilla.org/en-US/docs/Web/API/…:-|
Klasa FormData działa, jednak w iOS Safari (przynajmniej na iPhonie) nie byłem w stanie użyć rozwiązania Raphaela Schweikerta.
Mozilla Dev ma fajną stronę na temat manipulowania obiektami FormData .
Dodaj pusty formularz gdzieś na swojej stronie, określając typ:
Następnie utwórz obiekt FormData jako:
i postępuj jak w kodzie Rafaela .
źródło
Jeden problem, na który natknąłem się dzisiaj, myślę, że warto zwrócić uwagę na ten problem: jeśli adres URL wywołania ajax zostanie przekierowany, wówczas nagłówek typu treści: „multipart / form-data” może zostać utracony.
Na przykład pisałem na stronie http://server.com/context?param=x
Na karcie sieciowej Chrome zobaczyłem poprawny wieloczęściowy nagłówek tego żądania, ale potem przekierowanie 302 na http://server.com/context/?param=x (zwróć uwagę na ukośnik po kontekście)
Podczas przekierowania utracono nagłówek wieloczęściowy. Upewnij się, że żądania nie są przekierowywane, jeśli te rozwiązania nie działają dla Ciebie.
źródło
Wszystkie powyższe rozwiązania wyglądają dobrze i elegancko, ale obiekt FormData () nie oczekuje żadnego parametru, ale po utworzeniu instancji używa append (), tak jak napisano powyżej:
formData.append (nazwa.wartości; wartość.wartości);
źródło
Jeśli plik wejściowy
name
wskazuje tablicę i flagimultiple
, a ty analizowania całej kartyform
zFormData
, to nie jest konieczne, aby iteracyjnieappend()
pliki wejściowe.FormData
automatycznie obsłuży wiele plików.Zauważ, że
button type="button"
używa się zwykłego , a nietype="submit"
. To pokazuje, że nie ma zależności od korzystaniasubmit
z tej funkcji.Wynikowy
$_FILES
wpis jest taki w narzędziach programistycznych Chrome:Uwaga: zdarzają się przypadki, w których niektóre obrazy będą ładowane w porządku, gdy zostaną przesłane jako pojedynczy plik, ale nie powiedzie się, gdy zostaną przesłane w zestawie wielu plików. Objawem jest to, że raporty PHP są puste
$_POST
i$_FILES
AJAX nie zgłasza żadnych błędów. Problem występuje w Chrome 75.0.3770.100 i PHP 7.0. Wydaje się, że dzieje się tak tylko z 1 z kilkudziesięciu zdjęć w moim zestawie testowym.źródło
Starsze wersje IE nie obsługują FormData (pełna lista przeglądarek FormData znajduje się tutaj: https://developer.mozilla.org/en-US/docs/Web/API/FormData ).
Możesz użyć wtyczki jquery (na przykład http://malsup.com/jquery/form/#code-samples ) lub możesz użyć rozwiązania opartego na ramce IFrame do wysyłania danych wieloczęściowych za pośrednictwem ajax: https: // developer. mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
źródło
PHP
jQuery i formularz HTML
źródło
źródło