JavaScript: Prześlij plik

189

Powiedzmy, że mam ten element na stronie:

<input id="image-file" type="file" />

Spowoduje to utworzenie przycisku, który pozwoli użytkownikom strony internetowej wybrać plik za pomocą okna dialogowego „Otwórz plik ...” w przeglądarce.

Powiedzmy, że użytkownik klika wspomniany przycisk, wybiera plik w oknie dialogowym, a następnie klika przycisk „Ok”, aby zamknąć okno dialogowe.

Wybrana nazwa pliku jest teraz przechowywana w:

document.getElementById("image-file").value

Powiedzmy, że serwer obsługuje wieloczęściowe testy POST pod adresem URL „/ upload / image”.

Jak wysłać plik do „/ upload / image”?

W jaki sposób mogę również oczekiwać powiadomienia o zakończeniu przesyłania pliku?

YummyBánhMì
źródło
2
JavaScript nie obsługuje przesyłania, ponieważ jest po stronie serwera. Skrypt po stronie serwera odbierze plik, a następnie go przeniesie. Dla php z folderu tymczasowego do żądanego folderu.
Bakudan,
15
Zagłosowano ponownie otworzyć, ponieważ pytanie dotyczy POJS (zwykłego starego javascript), a nie jQuery.
e2-e4

Odpowiedzi:

95

Chyba, że próbujesz przesłać plik za pomocą ajax, po prostu przesłać formularz do /upload/image.

<form enctype="multipart/form-data" action="/upload/image" method="post">
    <input id="image-file" type="file" />
</form>

Jeśli chcesz załadować obraz w tle (np. Bez przesyłania całego formularza), możesz użyć ajax:

Matt Ball
źródło
lub rozmiar iframe 0x0 ze skryptem przesyłającym obraz wewnątrz jego src = "" i opublikuj formularz za pomocą target = "iframeId" odczytując wynik zdarzenia src .load iframe, które można powiązać na przykład za pomocą jQuery.
Dmitry,
11
Obecnie możliwe jest głosowanie za pośrednictwem Javascript i Ajax, patrz: stackoverflow.com/a/10811427/694469 (nie głosowałem za tym).
KajMagnus
35
@KajMagnus, prawdopodobnie miałeś na myśli „upload”, ale przypadkowo powiedziałeś „upvote”
Samuel Allan
85

Pure JS

Opcji pobierania można użyć opcjonalnie z funkcją Oczekuj na wypróbowanie

let photo = document.getElementById("image-file").files[0];
let formData = new FormData();

formData.append("photo", photo);
fetch('/upload/image', {method: "POST", body: formData});

Podejście starej szkoły - xhr

let photo = document.getElementById("image-file").files[0];  // file from input
let req = new XMLHttpRequest();
let formData = new FormData();

formData.append("photo", photo);                                
req.open("POST", '/upload/image');
req.send(formData);

PODSUMOWANIE

  • Po stronie serwera można odczytać oryginalną nazwę pliku (i inne informacje), która jest automatycznie uwzględniana na żądanie przeglądarki w filenameparametrze formData.
  • NIE musisz ustawiać nagłówka żądania Content-Typena multipart/form-data- zostanie to ustawione automatycznie przez przeglądarkę.
  • Zamiast tego /upload/imagemożesz użyć pełnego adresu jak http://.../upload/image.
  • Jeśli chcesz wysłać wiele plików w jednym żądaniu, użyj multipleatrybutu: <input multiple type=... />i dołącz wszystkie wybrane pliki do formData w podobny sposób (np. photo2=...files[2];... formData.append("photo2", photo2);)
  • Możesz dołączyć dodatkowe dane (json), aby poprosić np. let user = {name:'john', age:34}W ten sposób:formData.append("user", JSON.stringify(user));
  • Te rozwiązania powinny działać we wszystkich głównych przeglądarkach.
Kamil Kiełczewski
źródło
Pracuj dla mnie idealnie.
Trieu Nguyen,
formData === formularz przesłaniaenctype="multipart/form-data"
xgqfrms
Dostaję błądnet::ERR_ABORTED 405 (Method Not Allowed)
Hidayt Rahman
@HidaytRahman ten błąd zwykle pojawia się, gdy serwer nie implementuje metody POST dla twojego adresu URL
Kamil Kiełczewski
1
Dziwne - zgodnie z twoim nagłówkiem myślałem, że nie potrzebujemy już serwera: D
Hidayt Rahman