J'ai lu ceci et cette question qui semble suggérer que le type de fichier MIME pourrait être vérifié en utilisant javascript côté client. Maintenant, je comprends que la vraie validation doit encore être faite côté serveur. Je souhaite effectuer une vérification côté client pour éviter un gaspillage inutile des ressources du serveur.
Pour tester si cela peut être fait côté client, j'ai changé l'extension d'un JPEG
fichier de test .png
et choisi le fichier à télécharger. Avant d'envoyer le fichier, j'interroge l'objet fichier à l'aide d'une console javascript:
document.getElementsByTagName('input')[0].files[0];
Voici ce que j'obtiens sur Chrome 28.0:
Fichier {webkitRelativePath: "", lastModifiedDate: Tue 16 Oct 2012 10:00:00 GMT + 0000 (UTC), nom: "test.png", type: "image / png", size: 500055…}
Il indique que le type est, image/png
ce qui semble indiquer que la vérification est effectuée en fonction de l'extension de fichier au lieu du type MIME. J'ai essayé Firefox 22.0 et cela me donne le même résultat. Mais selon les spécifications du W3C , le reniflage MIME devrait être implémenté.
Ai-je raison de dire qu'il n'y a aucun moyen de vérifier le type MIME avec javascript pour le moment? Ou est-ce que je manque quelque chose?
la source
I want to perform a client side checking to avoid unnecessary wastage of server resource.
Je ne comprends pas pourquoi vous dites que la validation doit être faite côté serveur, mais que vous voulez ensuite réduire les ressources du serveur. Règle d'or: ne faites jamais confiance aux commentaires des utilisateurs . Quel est l'intérêt de vérifier le type MIME côté client si vous ne faites que le faire côté serveur. C'est sûrement un «gaspillage inutile de ressources client »?type
propriété desFile
objets. Le code source du webkit, par exemple, révèle cette vérité. Il est possible d'identifier avec précision les fichiers côté client en recherchant, entre autres, des "octets magiques" dans les fichiers. Je travaille actuellement sur une bibliothèque MIT (dans le peu de temps libre dont je dispose) qui fera exactement cela. Si mes progrès vous intéressent, jetez un œil à github.com/rnicholus/determinater .image/jpeg
et que vous ne l'avez pas réellement modifié en changeant l'extension?Réponses:
Vous pouvez facilement déterminer le type de fichier MIME avec JavaScript
FileReader
avant de le télécharger sur un serveur. Je conviens que nous devrions préférer la vérification côté serveur plutôt que côté client, mais la vérification côté client est toujours possible. Je vais vous montrer comment et fournir une démo fonctionnelle en bas.Vérifiez que votre navigateur prend en charge à la fois
File
etBlob
. Tous les principaux devraient.Étape 1:
Vous pouvez récupérer les
File
informations d'un<input>
élément comme celui-ci ( ref ):Voici une version glisser-déposer de ce qui précède ( ref ):
Étape 2:
Nous pouvons maintenant inspecter les fichiers et découvrir les en-têtes et les types MIME.
✘ Méthode rapide
Vous pouvez naïvement demander à Blob le type MIME du fichier qu'il représente en utilisant ce modèle:
Pour les images, les types MIME reviennent comme suit:
Attention: le type MIME est détecté à partir de l'extension de fichier et peut être trompé ou usurpé. On peut renommer a
.jpg
en a.png
et le type MIME sera signalé commeimage/png
.✓ Méthode appropriée d'inspection de l'en-tête
Pour obtenir le type MIME de bonne foi d'un fichier côté client, nous pouvons aller plus loin et inspecter les premiers octets du fichier donné pour les comparer aux soi-disant nombres magiques . Soyez averti que ce n'est pas tout à fait simple car, par exemple, JPEG a quelques «nombres magiques». C'est parce que le format a évolué depuis 1991. Vous pourriez vous en tirer en ne vérifiant que les deux premiers octets, mais je préfère vérifier au moins 4 octets pour réduire les faux positifs.
Exemple de signatures de fichier JPEG (4 premiers octets):
Voici le code indispensable pour récupérer l'en-tête du fichier:
Vous pouvez ensuite déterminer le type MIME réel comme ceci (plus de signatures de fichiers ici et ici ):
Acceptez ou rejetez les téléchargements de fichiers à votre guise en fonction des types MIME attendus.
Démo
Voici une démo fonctionnelle pour les fichiers locaux et distants (j'ai dû contourner CORS juste pour cette démo). Ouvrez l'extrait de code, exécutez-le et vous devriez voir trois images distantes de types différents affichés. En haut, vous pouvez sélectionner une image locale ou un fichier de données, et la signature du fichier et / ou le type MIME seront affichés.
Notez que même si une image est renommée, son vrai type MIME peut être déterminé. Voir ci-dessous.
Capture d'écran
Afficher l'extrait de code
la source
fileReader.readAsArrayBuffer(blob.slice(0,4))
? (2) Afin de copier / coller des signatures de fichiers, l'en-tête ne devrait-il pas être construit avec des 0 en têtefor(var i = 0; i < bytes.length; i++) { var byte = bytes[i]; fileSignature += (byte < 10 ? "0" : "") + byte.toString(16); }
?FF D8 FF E2
= CANNON EOS JPEG FILE,FF D8 FF E3
= SAMSUNG D500 JPEG FILE. La partie clé de la signature JPEG n'est que de 2 octets, mais pour réduire les faux positifs, j'ai ajouté les signatures de 4 octets les plus courantes. J'espère que cela aide.fileReader.readAsArrayBuffer(blob.slice(0, 4))
Comme indiqué dans d'autres réponses, vous pouvez vérifier le type mime en vérifiant la signature du fichier dans les premiers octets du fichier.
Mais ce que font les autres réponses, c'est de charger le fichier entier en mémoire afin de vérifier la signature, ce qui est très coûteux et pourrait facilement geler votre navigateur si vous sélectionnez un gros fichier par accident ou non.
la source
readyState
sera toujoursFileReader.DONE
dans le gestionnaire d'événements ( spécification W3C ) même s'il y avait une erreur - la vérification ne devrait-elle pas être si à la(!e.target.error)
place?Pour tous ceux qui cherchent à ne pas l'implémenter eux-mêmes, Sindresorhus a créé un utilitaire qui fonctionne dans le navigateur et qui a les mappages d'en-tête-mime pour la plupart des documents que vous pourriez souhaiter.
https://github.com/sindresorhus/file-type
Vous pouvez combiner la suggestion de Vitim.us de ne lire que les X premiers octets pour éviter de tout charger en mémoire avec l'utilisation de cet utilitaire (exemple dans es6):
la source
"file-type": "12.4.0"
fonctionnait et je devais l'utiliserimport * as fileType from "file-type";
Si vous voulez juste vérifier si le fichier téléchargé est une image, vous pouvez simplement essayer de le charger dans la
<img>
balise pour vérifier tout rappel d'erreur.Exemple:
la source
C'est ce que tu dois faire
Si vous souhaitez vérifier les types de fichiers image,
la source
Voici une implémentation de Typescript qui prend en charge webp. Ceci est basé sur la réponse JavaScript de Vitim.us.
la source
Comme Drake le déclare, cela pourrait être fait avec FileReader. Cependant, ce que je présente ici est une version fonctionnelle. Tenez compte du fait que le gros problème avec JavaScript est de réinitialiser le fichier d'entrée. Eh bien, cela se limite uniquement au JPG (pour les autres formats, vous devrez changer le type mime et le nombre magique ):
Tenez compte du fait que cela a été testé sur les dernières versions de Firefox et Chrome, et sur IExplore 10.
Pour une liste complète des types de mime, consultez Wikipedia .
Pour une liste complète des nombres magiques, consultez Wikipedia .
la source
Voici une extension de la réponse de Roberto14 qui fait ce qui suit:
CECI N'AUTORISE QUE DES IMAGES
Vérifie si FileReader est disponible et revient à la vérification d'extension s'il n'est pas disponible.
Donne une alerte d'erreur si ce n'est pas une image
S'il s'agit d'une image, il charge un aperçu
** Vous devez toujours faire la validation côté serveur, c'est plus une commodité pour l'utilisateur final qu'autre chose. Mais c'est pratique!
la source
La réponse courte est non.
Comme vous le constatez, les navigateurs dérivent
type
de l'extension de fichier. L'aperçu Mac semble également fonctionner avec l'extension. Je suppose que c'est parce qu'il lit plus rapidement le nom du fichier contenu dans le pointeur, plutôt que de rechercher et de lire le fichier sur le disque.J'ai fait une copie d'un jpg renommé avec png.
J'ai pu obtenir systématiquement ce qui suit à partir des deux images dans Chrome (devrait fonctionner dans les navigateurs modernes).
ÿØÿàJFIFÿþ;CREATOR: gd-jpeg v1.0 (using IJG JPEG v62), quality = 90
Ce que vous pourriez pirater un contrôle String.indexOf ('jpeg') pour le type d'image.
Voici un violon à explorer http://jsfiddle.net/bamboo/jkZ2v/1/
La ligne ambiguë que j'ai oublié de commenter dans l'exemple
console.log( /^(.*)$/m.exec(window.atob( image.src.split(',')[1] )) );
Le code violon utilise le décodage base64 qui ne fonctionnera pas dans IE9, j'ai trouvé un bel exemple utilisant le script VB qui fonctionne dans IE http://blog.nihilogic.dk/2008/08/imageinfo-reading-image-metadata-with.html
Le code pour charger l'image a été pris de Joel Vardy, qui fait un redimensionnement de la toile d'image sympa côté client avant le téléchargement, ce qui peut être intéressant https://joelvardy.com/writing/javascript-image-upload
la source
JFIF
place, ilAPP0
n'est pas nécessaire de contenir JFIF dans les fichiers EXIF-JPEG, donc c'est aussi le cas).