ใน JS front-end คุณใช้ XMLHTTTPREQUEST 2 เพื่ออัปโหลดรูปภาพไปยังเซิร์ฟเวอร์ เป็นเรื่องปกติบนพีซีและโทรศัพท์มือถือส่วนใหญ่ แต่การอัปโหลดบนโทรศัพท์ Android จำนวนน้อยล้มเหลว เมื่อดูภาพบนเซิร์ฟเวอร์จำนวนไบต์จะปรากฏขึ้นคือ 0 นี่คือรหัสหลักสำหรับการอัปโหลดภาพ:
HTML
<input type = "file" id = "เลือก" capture = "camera" accept = "image/*"> javascriptvar filechooser = document.getElementById ("เลือก"); fileChooser.onchange = function () {var _this = $ (this); ถ้า (! (files.length> 1) {Alert ("เพียง 1 ภาพเท่านั้นที่สามารถอัปโหลดได้ในแต่ละครั้ง"); return;} files.foreach (ฟังก์ชั่น (ไฟล์, i) {ถ้า (! /// (?: jpeg | png | gif) file.type);}; reader.readasdataUrl (ไฟล์);});}; ฟังก์ชั่นอัปโหลด (basest, type) {var xhr = ใหม่ xmlhttprequest (); var text = window.atob (basestr.split (",") [1]) text.length; i ++) {buffer [i] = text.charcodeat (i);} var blob = getBlob (บัฟเฟอร์, ประเภท); var formData = ใหม่ formData (); (xhr.readystate == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.responsetext); console.log (JSondata);}}; // ใช้เหตุการณ์ความคืบหน้าเพื่อแสดงข้อมูลการส่งข้อมูล E.total)/2; // ใช้ pecent เพื่อแสดงความคืบหน้าการอัปโหลด}, false); xhr.send (formData);} ฟังก์ชั่น getBlob (บัฟเฟอร์, รูปแบบ) {var builder = window.webkitblobbuilder || window.mozblobbuilder; if (builder) {var builder = ใหม่ builder (); builder.append (บัฟเฟอร์); return builder.getBlob (รูปแบบ);} else {ส่งคืน window.blob ใหม่ ([บัฟเฟอร์], {ประเภท: รูปแบบ};รหัสข้างต้นใช้ FormData เพื่อใช้การส่งข้อมูลแบบฟอร์ม FormData เป็นประเภทข้อมูลใหม่ที่ออกแบบมาสำหรับ XHR2 การใช้มันเราสามารถสร้าง HTML <Form> ใน JavaScript ในเวลาจริงและส่งแบบฟอร์มผ่าน AJAX ในรหัสข้างต้นฟิลด์ในแบบฟอร์มที่ส่งมีชื่อว่า ImageFile และค่าคือ BLOB ซึ่งเป็นไฟล์ blob ที่สร้างขึ้นและส่งคืนโดยฟังก์ชัน getBlob การอัปโหลดไฟล์ด้วยวิธีนี้เป็นเรื่องง่ายและใช้งานง่าย
จากนั้นเราได้รับและบันทึกรูปภาพบนเซิร์ฟเวอร์และส่งคืนข้อมูลของรูปภาพที่อัปโหลด
นี่คือตัวอย่างของรหัส node.js:
var q = ต้องการ ('q'); var fs = require ('fs'); var path = ต้องการ ('path'); var actoidable = ต้องการ ('atonidable'); var moment = ต้องการ ('moment'); var imageUpload = function () {}; imageUpload.prototype formidable.inmingform (); form.parse (req, deverred.makenoderesolver ()); return reterred.promise;}; imageUpload.prototype.uploadimagetest = ฟังก์ชั่น (req) pathName); return this.useformparsecallback (req). จากนั้น (ฟังก์ชั่น (ไฟล์) {var file = ไฟล์ [1] .imagefile; var fileType = ไฟล์ [1] .ImageFile.type.split ('/') [1]; var newfilename = 'upload_' 10) + '.' + fileType; var readStream = fs.createReadStream (file.path); deferred.promise.then (function () {fs.unlinksync (file.path); return {filename: newfilename, filepath: '/' + pathname + newfilename, filesize: file.size/1024> 1024? "kb"};});});}; module.exports = imageUpload;เราใช้แพ็คเกจที่น่าเกรงขามเพื่อรับข้อมูลไฟล์ที่อัปโหลดแล้วบันทึกไฟล์ไปยังไดเรกทอรี/public/uploadimgs/dealinfo (สมมติว่าสาธารณะได้ถูกตั้งค่าเป็นไดเรกทอรีรากคงที่ในด่วน) และเปลี่ยนชื่อภาพตามกฎที่ระบุเพื่อให้แน่ใจว่าภาพที่อัปโหลด นอกจากนี้ Q ถูกใช้ในรหัสเพื่อหลีกเลี่ยงการใช้ฟังก์ชั่นการโทรกลับโดยตรงเพื่อฟังก์ชั่นฟังก์ชั่นแยกต่างหากที่ดีขึ้น
รหัสข้างต้นทำงานตามปกติบนเบราว์เซอร์พีซีและอุปกรณ์มือถือหลักส่วนใหญ่ แต่อุปกรณ์ Android จำนวนน้อยจะมีไบต์อิมเมจที่อัปโหลดเป็น 0 ด้วยเหตุผลเฉพาะคุณสามารถดูคำอธิบายบนหน้าเว็บต่อไปนี้:
นั่นหมายความว่านี่เป็นข้อผิดพลาดใน Android!
แล้วจะแก้ปัญหาได้อย่างไร?
ในความเป็นจริงคำตอบสามารถพบได้จากหน้าเว็บที่ระบุไว้ด้านบนนั่นคือเราต้องเปลี่ยนวิธีการอัปโหลดไฟล์ ใน XHR2 นอกเหนือจากการอัปโหลดไฟล์ใน BLOB คุณยังสามารถอัปโหลดไฟล์ใน ArrayBuffer ได้
ต่อไปนี้เป็นรหัส JavaScript ที่แก้ไขแล้ว:
var filechooser = document.getElementById ("เลือก"); filechooser.onchange = function () {var _this = $ (นี่); ถ้า (! this.files.length) return; var files = array.prototype.slice.call (this.files); เวลา "); return;} files.foreach (ฟังก์ชั่น (ไฟล์, i) {ถ้า (! /// (?: jpeg | png | gif) /i.test (file.type)) return; var reader = new filereader (); reader.onload = function () {var result = this.result; file.type);}; reader.readasdataUrl (ไฟล์);});}; ฟังก์ชั่นอัปโหลด (basest, type) {var xhr = ใหม่ xmlhttprequest (); var text = window.atob (basestr.split (",") [1]) text.length; i ++) {buffer [i] = text.charcodeat (i);} xhr.open ('post', '/uploadtest? fileType ='+type.split ('/') [1]); (xhr.readystate == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.responsetext); console.log (JSondata);}}; // ใช้เหตุการณ์ความคืบหน้าเพื่อแสดงข้อมูลการส่งข้อมูล e.total)/2; // ใช้ pecent เพื่อแสดงความคืบหน้าการอัปโหลด}, false); xhr.send (buffer.buffer); // อัปโหลดรูปภาพใน ArrayBuffer}ฉันจะเน้นการเปลี่ยนแปลง การอัปโหลดรูปภาพในโหมด ArrayBuffer จะต้องเพิ่ม requestheader ของ 'Application/Octet-Stream' มิฉะนั้นเซิร์ฟเวอร์จะไม่สามารถตอบสนองต่อคำขอได้ นอกจากนี้โดยการอัปโหลดรูปภาพด้วยวิธีนี้เราไม่สามารถรับประเภทไฟล์จากข้อมูลแบบฟอร์มได้ เราสามารถส่งประเภทไฟล์ไปยังเซิร์ฟเวอร์ในลักษณะการสืบค้นและเซิร์ฟเวอร์สร้างไฟล์ที่เกี่ยวข้องตามประเภทไฟล์ ต่อไปนี้เป็นรหัสเซิร์ฟเวอร์หลังจากการแก้ไขเล็กน้อย:
imageUpload.prototype.uploadimagetest = function (req) {var pathname = 'uploadimgs/dealInfo/'; var uploadPath = path.join (__ dirname, '../../public/', var = filde = fildive req.Query.FileType? fs.createwritestream (uploadpath + newfilename); var deferred = q.defer (); readstream.pipe (writestream); readstream.on ('end', deferred.makenoderesolver ()) newfilename, filepath: '/' + pathname + newfilename, filesize: file.size/1024> 1024?รหัสที่แก้ไขสามารถรองรับโทรศัพท์ Android รวมถึงเบราว์เซอร์ WeChat โปรดทราบว่าโทรศัพท์ Android ทุกเครื่องจะไม่มีปัญหานี้ หากคุณพบว่าคุณไม่สามารถอัปโหลดภาพบนโทรศัพท์ Android โดยเฉพาะในเบราว์เซอร์ WeChat คุณสามารถลองใช้วิธีการข้างต้นได้
ด้านบนเป็นวิธีแก้ปัญหาในการอัปโหลดรูปภาพเป็น 0 โดยใช้ XMLHTTPREQUEST 2 ในเบราว์เซอร์ WeChat ของโทรศัพท์มือถือ Android ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน!