Dans JS frontal, vous utilisez XMLHttpRequest 2 pour télécharger des images sur le serveur. Il est normal sur PC et la plupart des téléphones mobiles, mais le téléchargement sur un petit nombre de téléphones Android échoue. Lors de la visualisation de l'image sur le serveur, le nombre d'octets s'affiche est 0. Voici le code de base pour télécharger l'image:
Html
<input type = "file" id = "choisir" capture = "caméra" accepter = "image / *"> javascriptvar filechooser = document.getElementyid ("choisir"); fileChooser.onchange = function () {var _this = $ (this); if (! this.files.length) return; var filets = array.prototype.slice.call (this) return); (files.length> 1) {alert ("seule 1 image peut être téléchargée à un moment"); return;} files.ForEach (function (file, i) {if (! /// (return; jpeg | png | gif) /i.test (file.type))) file.type);}; reader.readaSDataurl (fichier);});}; fonction upload (basest, type) {var xhr = new xmlhttprequest (); var text = window.atoB (Basetstr.split (",") [1]); var tampon = new uint8array (text.Legth); var prime = 0; pour (var i = 0; text.length; i ++) {buffer [i] = text.charcodeat (i);} var blob = getBlob (tampon, type); var formdata = new formData (); formdata.append ('imagefile', blob); (xhr.readystate == 4 && xhr.status == 200) {var jSondata = JSON.Parse (xhr.ResponSeText); console.log (jSondata);}}; // utilisez un événement de progression pour afficher les données envoyant des progrès xhr.upload.addeventedener ('progress', fonction (e) {piclai E.Total) / 2; // Utilisez PECENT pour afficher le téléchargement de progrès}, false); xhr.send (formdata);} fonction getBlob (tampon, format) {var builder = window.webkitblobuilder || window.mozBlobBuilder; if (builder) {var builder = new Builder (); builder.append (buffer); return builder.getblob (format);} else {return new Window.blob ([buffer], {type: format});}}Le code ci-dessus utilise FormData pour implémenter la soumission des données du formulaire. FormData est un nouveau type de données conçu pour XHR2. L'utilisation, nous pouvons facilement créer HTML <form> en JavaScript en temps réel et soumettre le formulaire via AJAX. Dans le code ci-dessus, le champ dans le formulaire soumis est nommé ImageFile et la valeur est blob, qui est un blob de fichier construit et renvoyé par la fonction getBlob. Le téléchargement de fichiers via cette méthode est simple et intuitif.
Ensuite, nous recevons et enregistrons l'image sur le serveur et renvoyons les informations de l'image téléchargée.
Voici un exemple de code Node.js:
var q = require ('q'); var fs = require ('fs'); var path = required ('path'); var formidable = required ('formidable'); var Moment = require ('Moment'); var imageupload = function () {}; imageupload.prototype.USEFORMPARSECALLBACK = nouveau = nouveau (req) {var Deferred = Q.Defer (); var form = neuf) formidable.incomingForm (); form.parse (req, deferred.makenoderesolver ()); return deferred.promis;}; imageupload.prototype.uploadImageTest = function (req) {var pathname = 'uploadimgs / dealinfo /' pathName); return this.UseFormParsEcallback (req) .then (fonction (fichiers) {var file = files [1] .imageFile; var fileType = file [1] .imageFile.type.split ('/') [1]; var newFileName = 'upload_' + Moment (). 10) + '. Deferred.promise.then (function () {fs.unLinkSync (file.path); return {filename: newFileName, filepath: '/' + pathname + newFileName, file size: file.size / 1024> 1024? (~~ (10 * file.Size / 1024/1024)) / 10 + "mb": ~ / 1024))) / 10 + "mb": ~ / 1024)) / 10 + "mb": ~ / 1024)) / 10 + "mb": ~ ~ ( + "Kb"};});});}; module.exports = imageupload;Nous utilisons le forfait formidable pour recevoir les données de fichier téléchargées, puis enregistrons le fichier dans le répertoire / public / uploadImgs / DealInfo (en supposant que le public a été défini sur le répertoire racine de Static dans Express), et renommera l'image en fonction des règles spécifiées pour s'assurer que l'image téléchargée ne sera pas surévaluée en raison du même nom. De plus, Q est utilisé dans le code pour éviter d'utiliser les fonctions de rappel directement pour mieux séparer les fonctions de fonction.
Le code ci-dessus fonctionne normalement sur les navigateurs PC et la plupart des appareils mobiles grand public, mais un petit nombre d'appareils Android auront les octets d'image téléchargés de 0. Pour des raisons spécifiques, vous pouvez voir les descriptions sur les pages Web suivantes:
Cela signifie que c'est un bug dans Android!
Alors, comment le résoudre?
En fait, la réponse peut être trouvée à partir de la page ci-dessus, c'est-à-dire que nous devons modifier la méthode de téléchargement de fichiers. Dans XHR2, en plus de télécharger des fichiers dans Blob, vous pouvez également télécharger des fichiers dans ArrayBuffer.
Ce qui suit est le code JavaScript frontal modifié:
var fileChoOser = Document.getElementById ("Choisissez"); fileChoOser.Onchange = function () {var _This = $ (this); if (! this.files.length) return; var files Temps "); return;} files.ForEach (function (file, i) {if (! //// (?: jpeg | png | gif) /i.test (file.type)) return; var Reader = new FileReader (); Reader.onLoad = function () {var result = this.result; upload (result, result, respect, file.type);}; reader.readaSDataurl (fichier);});}; fonction upload (basest, type) {var xhr = new xmlhttprequest (); var text = window.atoB (Basetstr.split (",") [1]); var tampon = new uint8array (text.Legth); var prime = 0; pour (var i = 0; text.length; i ++) {buffer [i] = text.charcodeat (i);} xhr.open ('post', '/ uploadtest? fileType =' + type.split ('/') [1]); xhr.setRequestHe (xhr.readystate == 4 && xhr.status == 200) {var jSondata = JSON.Parse (xhr.ResponSeText); console.log (jSondata);}}; // utilisez un événement de progression pour afficher les données envoyant des progrès xhr.upload.addeventedener ('progress', fonction (e) {piclai e.total) / 2; // Utiliser PECENT pour afficher le téléchargement de progrès}, false); xhr.send (buffer.buffer); // Télécharger l'image dans ArrayBuffer}Je vais mettre en évidence les modifications. Le téléchargement d'images en mode ArrayBuffer doit ajouter le pointage de demande de «Application / Octet-Stream», sinon le serveur ne pourra pas répondre à la demande. De plus, en téléchargeant des images de cette manière, nous ne pouvons pas obtenir le type de fichier à partir des données de formulaire. Nous pouvons transmettre le type de fichier au serveur de manière requête et le serveur génère le fichier correspondant en fonction du type de fichier. Ce qui suit est le code du serveur après une petite quantité de modification:
ImageUpLoad.prototype.uploadImageTest = fonction (req) {var pathname = 'uploadImgs / DealInfo /'; var uploadPath = path.join (__ dirname, '../../public/', pathname); return this.UseFormAscallback (req) .Then (function (file) {var fichier = file [1] .file; req.query.FileType? fs.CreateWRiteStream (uploadPath + newFileName); var Deferred = q.defer (); readStream.Pipe (eredestream); readstream.on ('end', Deferred.Makenoderesolver ()); readstream deferred.promise.then (furename () {fs.unlinkSync (file.pathe); newFileName, filepath: '/' + pathname + newFileName, file size: file.size / 1024> 1024?Le code modifié peut prendre en charge les téléphones Android, y compris les navigateurs WeChat. Notez que tous les téléphones Android n'auront pas ce problème. Si vous constatez que vous ne pouvez pas télécharger d'images sur les téléphones Android, en particulier dans les navigateurs WeChat, vous pouvez essayer la méthode ci-dessus.
Ce qui précède est la solution pour télécharger des images sur 0 à l'aide de XMLHTTPRequest 2 dans le navigateur WeChat des téléphones mobiles Android. J'espère que ce sera utile à tous!