Di JS front-end, Anda menggunakan XMLHTTPREQUEST 2 untuk mengunggah gambar ke server. Ini normal di PC dan sebagian besar ponsel, tetapi mengunggah sejumlah kecil ponsel Android gagal. Saat melihat gambar di server, jumlah byte ditampilkan adalah 0. Berikut adalah kode inti untuk mengunggah gambar:
Html
<input type = "file" id = "pilih" capture = "camera" accept = "image/*"> javaScriptvar filechooser = document.geteLementById ("pilih"); filechooser.onchange = function () {var _this = $ (this); if (! this.files.files.length) return; arrefs. (file.length> 1) {waspada ("Hanya 1 gambar yang dapat diunggah pada suatu waktu"); return;} file.foreach (function (file, i) {if (! /// (?: jpeg | png | gif); evance load (file.type)) kembali; var reader = new filereader (); reader.on load (file.type)) return; var reader = new filereader (); reader.on load = function = function = function = function = function = function (function (function (function (function (function) (var) {{loader (File.type) (var); file.type);}; reader.readasDataurl (file);});}; unggah fungsi (basestr, type) {var xhr = new xmlHttprequest (); var text = window.atob (basestr.split (",") [1]); var buffer = var uint8 new (taps. text.length; i ++) {buffer [i] = text.charcodeat (i);} var blob = getBlob (buffer, type); var formdata = new formData (); formdata.append ('imageFile', blob); xhr.open ('pos', '/umploadte (fungsi'; xhr. (xhr.readystate == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.Responsetext); console.log (jsondata);}}; // menggunakan progress event untuk menampilkan data yang mengirim kemajuan xhr.upload.addeventener (~ ~ {~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e.total)/2; // Gunakan Pecent untuk menampilkan kemajuan unggahan}, false); xhr.send (formdata);} fungsi getBlob (buffer, format) {var builder = window.webkitblobbuilder || window.mozblobbuilder; if (builder) {var builder = new builder (); builder.append (buffer); return builder.getBlob (format);} else {return window.blob baru ([buffer], {type: format});}}} baruKode di atas menggunakan formdata untuk mengimplementasikan pengiriman data formulir. FormData adalah tipe data baru yang dirancang untuk XHR2. Menggunakannya, kita dapat dengan mudah membuat HTML <Form> di JavaScript secara real time dan mengirimkan formulir melalui AJAX. Dalam kode di atas, bidang dalam formulir yang dikirimkan bernama ImageFile dan nilainya gumpalan, yang merupakan file gumpalan yang dibangun dan dikembalikan oleh fungsi GetBlob. Mengunggah file melalui metode ini sederhana dan intuitif.
Kemudian kami menerima dan menyimpan gambar di server dan mengembalikan informasi gambar yang diunggah.
Berikut adalah contoh kode Node.js:
var q = membutuhkan ('q'); var fs = membutuhkan ('fs'); var path = membutuhkan ('path'); var formidable = memerlukan ('tangguh'); var moment = membutuhkan ('momen'); var imageupload = formule () {}; imageupload = qroteForm.useFormParsecallback = req) {req); checidable.incomingform (); form.parse (req, deferred.makenoderesolver ()); return ditangguhkan.promise;}; imageupload.prototype.uploadimagetest = function (requbl) {var pathname = 'unggahan/dealinfo/'; var publ.publ.publ. pathname); kembalikan this.useFormParsecallback (req) .then (function (file) {var file = file [1] .imageFile; var filetype = file [1] .imageFile.type.split ('/') [1]; var newfileName = 'unggah_' + momen (). 10) + '.' + FileType; var readStream = fs.createreadstream (file.path); var writeStream = fs.createWriteStream (unggahPath + newFileName); var ditangguhkan = q.defer (); readstream.pipe (writestream); readstream.on ('end' Deferred.promise.then (function () {fs.unlinksync (file.path); return {filename: newfileName, filepath: '/' + pathname + newFileName, filessize: file.size/1024> 1024? (~ ~ ~ 10 "Kb"};});});}; module.exports = imageupload;Kami menggunakan paket yang tangguh untuk menerima data file yang diunggah, dan kemudian menyimpan file tersebut ke direktori/unggah/unggah/dealInfo (dengan asumsi bahwa publik telah diatur ke direktori root statis di Express), dan mengubah nama gambar sesuai dengan aturan yang ditentukan untuk memastikan bahwa gambar yang diunggah tidak akan ditimpa karena nama yang sama. Selain itu, Q digunakan dalam kode untuk menghindari penggunaan fungsi panggilan balik secara langsung ke fungsi fungsi yang lebih terpisah.
Kode di atas berfungsi secara normal pada browser PC dan sebagian besar perangkat seluler utama, tetapi sejumlah kecil perangkat Android akan memiliki byte gambar yang diunggah 0. Untuk alasan tertentu, Anda dapat melihat deskripsi pada halaman web berikut:
Itu berarti ini adalah bug di Android!
Jadi bagaimana cara menyelesaikannya?
Bahkan, jawabannya dapat ditemukan dari halaman yang diberikan di atas, yaitu, kita harus mengubah metode unggahan file. Di XHR2, selain mengunggah file dalam gumpalan, Anda juga dapat mengunggah file di ArrayBuffer.
Berikut ini adalah kode javascript front-end yang dimodifikasi:
var filechooser = document.getElementById ("pilih"); filechooser.onchange = function () {var _this = $ (this); if (! this.files.length) return; var file = array.prototype.slice.call (ini. waktu "); return;} file.foreach (function (file, i) {if (! /// (?: jpeg | png | gif) /i.test (file.type)) return; var reader = new filereader (); reader.onload = function () {var result = this.result; unggah (); hasil,); file.type);}; reader.readasDataurl (file);});}; unggah fungsi (basestr, type) {var xhr = new xmlHttprequest (); var text = window.atob (basestr.split (",") [1]); var buffer = var uint8 new (taps. text.length; i ++) {buffer [i] = text.charcodeat (i);} xhr.open ('post', '/unggahtest? FileType ='+type.split ('/') [1]); xhr.setRequestHeader ('Tipe-Tipe', 'Aplikasi/Octet-Stream'); Octet-Stream '); xhr.setRequestHeader (' Content-Type ',' Application/Octet-Stream '); XHRAED'); FUMBREADE ('TYPECE', 'OCTETE/OCTECE (' OCTECE/OCTECE/OCTECE ('OCTECE/OCTECE ('); (xhr.readystate == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.Responsetext); console.log (jsondata);}}; // menggunakan progress event untuk menampilkan data yang mengirim kemajuan xhr.upload.addeventener (~ ~ {~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ e.total)/2; // Gunakan Pecent untuk menampilkan kemajuan unggahan}, false); xhr.send (buffer.buffer); // Unggah gambar di ArrayBuffer}Saya akan menyoroti perubahannya. Mengunggah gambar dalam mode arrayBuffer harus menambahkan permintaan 'aplikasi/oktet-stream', jika tidak server tidak akan dapat menanggapi permintaan. Selain itu, dengan mengunggah gambar dengan cara ini, kami tidak dapat memperoleh jenis file dari data formulir. Kami dapat meneruskan jenis file ke server dengan cara permintaan, dan server menghasilkan file yang sesuai sesuai dengan jenis file. Berikut ini adalah kode server setelah sedikit modifikasi:
ImageUpload.prototype.uploadimagetest = function (req) {var pathname = 'unggah/dealinfo/'; var unggahpath = path.join (__ dirname, '../public/', pathname); kembalikan this.useFormParsEsecallback (req) .then) .thene =); funche (funche) (return this.useFormParsEsecallback (req) .then) .then). Req.Query.filetype? fs.createWriteStream (unggahPath + newFileName); var ditangguhkan = q.defer (); readStream.pipe (writeStream); readStream.on ('end', ditangguhkan.makenoderesolver ()); return ditangguhkan. NewFileName, FilePath: '/' + pathname + newFileName, FileSize: File.size/1024> 1024?Kode yang dimodifikasi dapat mendukung ponsel Android, termasuk browser WeChat. Perhatikan bahwa tidak semua ponsel android akan memiliki masalah ini. Jika Anda menemukan bahwa Anda tidak dapat mengunggah gambar di ponsel Android, terutama di browser WeChat, Anda dapat mencoba metode di atas.
Di atas adalah solusi untuk mengunggah gambar ke 0 menggunakan XMLHTTPREQUEST 2 di browser WeChat ponsel Android. Saya harap ini akan membantu semua orang!