Selektor plików HTML - pobieranie wielu używanych plików

12

Podczas używania przeglądarki Firefox v73 w systemie Windows 7 wystąpił następujący problem:

W moim kodzie używam selektora wielu plików w HTML, aby przesłać równolegle do 100 plików:

<input type="file" id="files" name="files" multiple>

Pliki zostaną wysłane do interfejsu API REST, który następnie je przetworzy. Kiedy wybieram pojedynczy plik (w eksploratorze plików), który jest aktualnie używany, pojawia się komunikat o błędzie (prawdopodobnie przez okno), który mówi mi, że pliku nie można wybrać, ponieważ jest w użyciu. Jeśli próbuję wybrać wiele plików, które zawierają jeden lub więcej używanych plików, nie pojawia się żaden błąd, ale przesyłanie wydaje się być zatrzymane po osiągnięciu używanego pliku i oczekiwaniu na zwolnienie pliku. To prowadzi do żądania oczekiwania na limit czasu (w moim przypadku jest to 1 minuta).

Czy jest jakaś opcja, aby złapać problem (używany plik) przed próbą przesłania plików?

PS: Próbowałem tego samego w Chrome i zwraca błąd przed wysłaniem żądania do interfejsu API REST.

Kevin H.
źródło
Czy możesz pokazać swoje połączenie z ajaxem?
Islam Elshobokshy

Odpowiedzi:

3

To brzmi jak problem z systemem operacyjnym.
Coś blokuje dostęp do twojego pliku i to wymaga naprawy po twojej stronie.

Wątpię, czy będzie to powszechny problem i trudno jest zbudować rozwiązanie, nie mogąc doświadczyć tego samego problemu, ale jedną rzeczą, którą możesz spróbować, to przeczytać swoje pliki przed wysłaniem. Można to zrobić dość wygodnie za pomocą Blob.prototype.arrayBuffermetody, którą można wypełnić wieloskładnikowo.

Aby uniknąć dużej liczby operacji we / wy, możesz nawet spróbować odczytać tylko niewielką jej część dzięki Blob.prototype.slice() metodzie.

const input = document.getElementById('inp');
const btn = document.getElementById('btn');

btn.onclick = async(evt) => {
  testAllFilesAvailability(input.files)
    .then(() => console.log('all good'))
    .catch(() => console.log('some are unavailable'));
}

function testAllFilesAvailability(files) {
  return Promise.all(
    [...files].map(file =>
      file.slice(0, Math.min(file.size, 4)) // don't load the whole file
      .arrayBuffer() // Blob.prototype.arrayBuffer may require a polyfill
    )
  );
}
<pre>
1. Select some files from the input
2. Change one of this files name on your hard-drive or even delete it
3. Press the button
</pre>

<input type="file" multiple id="inp">
<button id="btn">Test Availability</button>

Kaiido
źródło
Dzięki Kaiido za rozwiązanie. Jest twoja reputacja +50. Ratownik!
Kevin H.
0

Aby wybrać wiele plików, dlaczego nie używasz https://github.com/blueimp/jQuery-File-Upload

RavinduKD
źródło
Korzystanie z jQuery nie jest obecnie dla mnie opcją ze względu na ograniczenia techniczne po stronie klienta.
Kevin H.