Wybieranie plików na urządzeniu lokalnym użytkownika i wchodzenie z nimi w interakcję to jedna z najczęściej używanych funkcji internetu. Umożliwia użytkownikom wybieranie plików i przesyłanie ich na serwer, na przykład podczas udostępniania zdjęć lub przesyłania dokumentów podatkowych. Umożliwia też witrynom odczytywanie i modyfikowanie tych danych bez konieczności przesyłania ich przez sieć. Na tej stronie znajdziesz informacje o tym, jak używać JavaScriptu do interakcji z plikami.
Nowoczesny interfejs File System Access API
Interfejs File System Access API umożliwia odczytywanie i zapisywanie plików oraz katalogów w systemie lokalnym użytkownika. Jest dostępna w większości przeglądarek opartych na Chromium, takich jak Chrome i Edge. Więcej informacji znajdziesz w artykule Interfejs File System Access API.
Interfejs File System Access API nie jest zgodny ze wszystkimi przeglądarkami, dlatego zalecamy używanie biblioteki pomocniczej browser-fs-access, która korzysta z nowego interfejsu API, gdy jest on dostępny, a w innych przypadkach używa starszych metod.
Praca z plikami w klasyczny sposób
Z tego przewodnika dowiesz się, jak korzystać z plików za pomocą starszych metod JavaScript.
Wybierz pliki
Pliki można wybierać na 2 główne sposoby: za pomocą elementu wejściowego HTML i za pomocą strefy przeciągania i upuszczania.
Element wejściowy HTML
Najłatwiejszym sposobem wybierania plików przez użytkowników jest użycie elementu
<input type="file">
, który jest obsługiwany w każdej popularnej przeglądarce. Po kliknięciu umożliwia użytkownikowi wybranie pliku lub wielu plików, jeśli uwzględniony jest atrybut multiple
, za pomocą wbudowanego interfejsu wyboru plików w systemie operacyjnym. Gdy użytkownik skończy wybierać pliki, uruchomi się zdarzenie change
elementu. Dostęp do listy plików możesz uzyskać z obiektu event.target.files
, który jest obiektem FileList
.
Każdy element w polu FileList
to obiekt File
.
<!-- The `multiple` attribute lets users select multiple files. -->
<input type="file" id="file-selector" multiple>
<script>
const fileSelector = document.getElementById('file-selector');
fileSelector.addEventListener('change', (event) => {
const fileList = event.target.files;
console.log(fileList);
});
</script>
W tym przykładzie użytkownik może wybrać wiele plików za pomocą wbudowanego interfejsu wyboru plików w systemie operacyjnym, a następnie zalogować każdy wybrany plik w konsoli.
Ograniczanie typów plików, które użytkownicy mogą wybierać
W niektórych przypadkach możesz ograniczyć typy plików, które użytkownicy mogą wybierać. Na przykład aplikacja do edycji obrazów powinna akceptować tylko obrazy, a nie pliki tekstowe. Aby ustawić ograniczenia dotyczące typu pliku, dodaj do elementu wejściowego atrybut accept
, aby określić, które typy plików są akceptowane:
<input type="file" id="file-selector" accept=".jpg, .jpeg, .png">
Niestandardowe przeciąganie i upuszczanie
W niektórych przeglądarkach element <input type="file">
jest też miejscem docelowym, co umożliwia użytkownikom przeciąganie i upuszczanie plików w aplikacji. Jednak to miejsce docelowe jest małe i może być trudne w użyciu. Zamiast tego po udostępnieniu podstawowych funkcji za pomocą elementu <input type="file">
możesz udostępnić dużą, niestandardową powierzchnię do przeciągania i upuszczania.
Wybierz strefę zrzutu
Powierzchnia docelowa zależy od projektu aplikacji. Możesz użyć całego okna, ale może się zdarzyć, że tylko część okna będzie odpowiednia jako obszar docelowy.

Aplikacja do kompresji obrazów Squoosh umożliwia użytkownikowi przeciągnięcie obrazu w dowolne miejsce okna i kliknięcie select an image (wybierz obraz), aby wywołać element <input type="file">
. Niezależnie od tego, co wybierzesz jako strefę upuszczania, upewnij się, że użytkownik wie, że może przeciągać pliki na tę powierzchnię.
Określanie strefy upuszczania
Aby włączyć element jako strefę przeciągania i upuszczania, utwórz odbiorniki dla 2 zdarzeń: dragover
i drop
.
Zdarzenie dragover
aktualizuje interfejs przeglądarki, aby wizualnie wskazać, że operacja przeciągania i upuszczania tworzy kopię pliku. Zdarzenie drop
jest wywoływane po tym, jak użytkownik upuści pliki na powierzchnię. Podobnie jak w przypadku elementu wejściowego, możesz uzyskać dostęp do listy plików z event.dataTransfer.files
, który jest obiektem FileList
. Każdy element w FileList
jest obiektem File
.
const dropArea = document.getElementById('drop-area');
dropArea.addEventListener('dragover', (event) => {
event.stopPropagation();
event.preventDefault();
// Style the drag-and-drop as a "copy file" operation.
event.dataTransfer.dropEffect = 'copy';
});
dropArea.addEventListener('drop', (event) => {
event.stopPropagation();
event.preventDefault();
const fileList = event.dataTransfer.files;
console.log(fileList);
});
event.stopPropagation()
i event.preventDefault()
zatrzymują domyślne działanie przeglądarki i umożliwiają uruchomienie Twojego kodu. Bez nich przeglądarka opuściłaby Twoją stronę i otworzyła pliki, które użytkownik przeciągnął do okna przeglądarki.
Aby zobaczyć demonstrację na żywo, zapoznaj się z artykułem Niestandardowe przeciąganie i upuszczanie.
A co z katalogami?
Niestety nie ma dobrego sposobu na uzyskanie dostępu do katalogu za pomocą JavaScriptu.
Atrybut webkitdirectory
elementu <input type="file">
umożliwia użytkownikowi wybranie katalogu lub katalogów. Jest obsługiwany w większości głównych przeglądarek z wyjątkiem Firefoksa na Androida i Safari na iOS.
Jeśli funkcja przeciągania i upuszczania jest włączona, użytkownik może spróbować przeciągnąć katalog do strefy upuszczania. Gdy zostanie wywołane zdarzenie upuszczania, będzie ono zawierać obiekt File
dla katalogu, ale nie zapewni dostępu do żadnych plików w tym katalogu.
Odczytywanie metadanych pliku
Obiekt File
zawiera metadane pliku. Większość przeglądarek podaje nazwę pliku, jego rozmiar i typ MIME, ale w zależności od platformy różne przeglądarki mogą podawać inne lub dodatkowe informacje.
function getMetadataForFileList(fileList) {
for (const file of fileList) {
// Not supported in Safari for iOS.
const name = file.name ? file.name : 'NOT SUPPORTED';
// Not supported in Firefox for Android or Opera for Android.
const type = file.type ? file.type : 'NOT SUPPORTED';
// Unknown cross-browser support.
const size = file.size ? file.size : 'NOT SUPPORTED';
console.log({file, name, type, size});
}
}
Możesz zobaczyć to w praktyce w input-type-file
wersji demonstracyjnej.
Odczytywanie zawartości pliku
Użyj FileReader
, aby wczytać do pamięci zawartość obiektu File
. Możesz polecić interfejsowi FileReader
odczytanie pliku jako bufora tablicy, adresu URL danych lub tekstu:
function readImage(file) {
// Check if the file is an image.
if (file.type && !file.type.startsWith('image/')) {
console.log('File is not an image.', file.type, file);
return;
}
const reader = new FileReader();
reader.addEventListener('load', (event) => {
img.src = event.target.result;
});
reader.readAsDataURL(file);
}
Ten przykład odczytuje File
podany przez użytkownika, a następnie przekształca go w adres URL danych i używa tego adresu URL do wyświetlania obrazu w elemencie img
.
Aby dowiedzieć się, jak sprawdzić, czy użytkownik wybrał plik obrazu, zapoznaj się z demonstracją read-image-file
.
Monitorowanie postępu odczytu pliku
Podczas odczytywania dużych plików warto zapewnić użytkownikowi informacje o postępie odczytu. W tym celu użyj zdarzenia progress
udostępnianego przez FileReader
. Zdarzenie progress
ma 2 właściwości: loaded
(przeczytana kwota) i total
(kwota do przeczytania).
function readFile(file) {
const reader = new FileReader();
reader.addEventListener('load', (event) => {
const result = event.target.result;
// Do something with result
});
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
const percent = (event.loaded / event.total) * 100;
console.log(`Progress: ${Math.round(percent)}`);
}
});
reader.readAsDataURL(file);
}
Baner powitalny: Vincent Botta, Unsplash