La détection des dossiers/répertoires en javascript FileList objets
J'ai récemment contribué à un certain code de Moodle qui utilise les fonctionnalités de HTML5 pour que les fichiers soient téléchargés dans les formes par glisser-déposer depuis le bureau (la partie du code est ici: https://github.com/moodle/moodle/blob/master/lib/form/dndupload.js pour référence).
Cela fonctionne bien, sauf quand un utilisateur traîne un dossier /répertoire au lieu d'un vrai fichier. Les ordures sont ensuite envoyées sur le serveur, mais avec le nom de fichier correspondant au dossier.
Ce que je cherche est un moyen facile et fiable de la détecter la présence d'un dossier dans le FileList objet, afin que je puisse l'ignorer (et probablement de retour d'un sympathique message d'erreur).
J'ai regardé à travers la documentation sur MDN, ainsi que d'un cadre plus général de la recherche sur le web, mais non mis en place quoi que ce soit. J'ai aussi regardé à travers les données dans les outils de développement Chrome et il semble que le 'type' de l'objet Fichier est constamment mis à "" pour les dossiers. Cependant, je ne suis pas tout à fait convaincu que c'est la plus fiable, la croix-navigateur de détection de la méthode.
Quelqu'un a une meilleure suggestion?
OriginalL'auteur davosmith | 2012-01-13
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas compter sur
file.type
. Un fichier sans extension aura un type de""
. Enregistrer un fichier texte avec un.jpg
extension et de le charger dans un fichier de contrôle, et son type d'affichage queimage/jpeg
. Et, un dossier nommé "someFolder.jpg" aura également son type deimage/jpeg
.Essayez de lire le fichier avec un
FileReader
. Si un répertoire est glissé dans, leFileReader
va augmenter laerror
événement:Heureusement, IE11, quand un répertoire est supprimé, la
e.dataTransfer.files
collection est vide.Chrome expose une propriété supplémentaire dans
e.dataTransfer
appeléitems
contenant une collection deDataTransferItem
objets. Sur chacun de ces objets, vous pouvez appeleritem.webkitGetAsEntry()
, qui retourne unEntry
objet. LeEntry
objet a des propriétésisDirectory
etisFile
:Il est intéressant de noter, dans mon expérimentation, tous les dossiers que j'ai regardé, a eu sa
File.size % 4096
à zéro. Cependant, bien sûr, certains fichiers ont ainsi.File.size
n'est pas un indicateur fiable de savoir si un fichier est en fait un dossier.Absolument. La découverte la plus surprenante pour moi a été que la taille n'était pas toujours 0 pour les dossiers. Le
% 4096
chose qui est intéressant. Certainement, plus la recherche est appelé pour. Comme, est de 4096 universelle, ou est-il spécifique à 64 bits de Windows 7?Bizarre, je recevais une taille de 0 de manière cohérente avec Win 7 (64 bits) (double-vérifier, mais essayé avec google Chrome/Firefox). Cependant, je commençais à 4096 octets (exactement) avec Ubuntu 11.10 (64 bits) (Chrome/Firefox).
Semble être la meilleure solution, que ce que vous avez dit, c'est juste pour gérer sur le serveur.
Ne PAS s'appuyer sur 4096 ou 0. Sur Linux, il peut être plus de 4096, par exemple 8192 ou plus, selon le nombre de fichiers le dossier contient des (ou utilisé pour contenir, comme la suppression de fichiers ne pas diminuer la taille). Sur Mac OS X, vous pouvez avoir divers petits nombres comme la taille des répertoires, comme 68, 102, 136, 170, et de croître car il contient plus de fichiers. Fondamentalement, la taille n'est pas quelque chose que vous pouvez utiliser.
OriginalL'auteur gilly3
J'ai aussi rencontré ce problème et en dessous c'est ma solution. En gros, j'ai pris ont une approche en deux volets:
(1) vérifier si le Fichier de l'objet est de taille grand, et le considèrent comme un véritable fichier si elle est de plus de 1 MO (je suis en supposant que les dossiers eux-mêmes ne sont jamais que les grandes).
(2) Si le Fichier de l'objet est inférieure à 1 MO, puis je l'ai lu à l'aide de FileReader "readAsArrayBuffer" la méthode. Lectures réussies appel 'onload', et je crois que cela indique que le fichier objet est un véritable fichier. Échec de lit appeler "onerror" et je considère que c'est un répertoire. Voici le code:
J'ai testé cette dans FF 26, Chrome 31, et Safari 6 et trois navigateurs appeler "onerror" lorsque la tentative de lecture des répertoires. Laissez-moi savoir si quelqu'un peut penser à un cas d'utilisation en cas d'échec.
Bonne prise avec readAsArrayBuffer - j'ai mis à jour le code pour prendre en compte la correction de bug (et pour fixer un autre bug : isLikelyFile est maintenant false si la taille du fichier est > 1 MO). Je n'ai pas eu du mal avec setInterval, mais bon de garder à l'esprit.
Notez que le
(f.size > 1048576)
optimisation dans certains cas être problématique, puisque la taille du dossier peut être plus grande que cela. Pour un dossier avec un grand nombre de fichiers, j'ai vérifié la taille de mon dossier temp (Windows 7), et c'est 2883584 octets...Devrait sans doute lire: si (f.taille > 1048576){ isLikelyFile = true; }
OriginalL'auteur Nick G.
Je propose d'appeler
FileReader.readAsBinaryString
sur leFile
objet. Dans Firefox, il déclenchera une Exception lorsque leFile
est unDirectory
. Je ne le faire que si leFile
répond aux conditions proposées par gilly3.Veuillez consulter mon blog à http://hs2n.wordpress.com/2012/08/13/detecting-folders-in-html-drop-area/ pour plus de détails.
Aussi, la version 21 de Google Chrome prend désormais en charge déposer des dossiers. Vous pouvez facilement vérifier si les éléments déposés sont des dossiers, et aussi lire leur contenu.
Malheureusement, je n'ai pas (côté client) solution pour les anciennes versions de Chrome.
OriginalL'auteur Richie
Un autre point à souligner est que le type est "" pour n'importe quel fichier qui a un inconnu extension. Essayez de télécharger un fichier nommé test.bla et le type sera vide. ET... essayez de faire glisser et de déposer un dossier nommé test.jpg - type sera mis à "image/jpeg". Pour être correct à 100%, vous ne pouvez pas dépendre de type uniquement (ou, si, vraiment).
Dans mes tests, des dossiers ont toujours été de taille 0 (sur FF et Chrome 64 bits Windows 7 et sous Linux Mint (Ubuntu essentiellement). Donc, mon dossier de vérification est juste vérifier si la taille est de 0 et il semble fonctionner pour moi dans notre environnement. Nous ne voulons pas de 0 octet fichiers téléchargés, soit si elle est de 0 octet le message revient à "Sauté - 0 octets (ou dossier)"
OriginalL'auteur Brian Pipa
Pour info, ce post va vous dire comment utiliser dataTransfer API google Chrome pour détecter le type de fichier: http://updates.html5rocks.com/2012/07/Drag-and-drop-a-folder-onto-Chrome-now-available
OriginalL'auteur Nam Nguyen