프론트 엔드 JS에서는 xmlhttprequest 2를 사용하여 서버에 이미지를 업로드합니다. PC와 대부분의 휴대폰에서는 정상이지만 소수의 Android 전화에 업로드하는 것이 실패합니다. 서버에서 이미지를 볼 때 표시되는 바이트 수는 0입니다. 이미지를 업로드하기위한 핵심 코드는 다음과 같습니다.
HTML
<input type = "file"id = "chelect"capture = "camera"acccept = "image/*"> javaScriptVar fileChooSer = document.getElementById ( "선택"); filechooser.onchange = function () {var _this = $ (this (! this.files.length) rength = array.protopoty. (files.length> 1) {alert ( "한 번에 단 1 개의 그림 만 업로드 할 수 있습니다"); return;} files.foreach (function (function, i) {if (! /// (? : jpeg | png | gif) /i.test (file.type)) return; var reader = new Filereader (); var gromate () file.type);}; reader.readasdataurl (file);});}; 함수 업로드 (Basest, type) {var xhr = new xmlhttprequest (); var text = window.atob (baseStr.split ( ") [1]) [1]) [1]); var prime = 0; (var i = 0); for i = 0); text.length; i ++) {buffer [i] = text.charcodeat (i);} var blob = getBlob (buffer, type); var formdata = new formdata (); formdata.append ( 'ImageFile', blob); xhr.open ( 'post', '/uploadtest '); == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.responsetext); console.log (jsondata);}}; // Progress 이벤트를 사용하여 진행 상황을 표시하기 위해 진행 xhr.upload.addeventListener ( 'progration', function (100 * e./2)). 업로드 진행}, false); xhr.send (formData);} 함수 getBlob (버퍼, 형식) {var builder = window.webkitblobBuilder || window.mozblobBuilder; if (builder) {var builder = new builder (); builder.append (buffer); return builder.getBlob (format);} else {return new Window.Blob ([buffer], {type : format});}}위의 코드는 FormData를 사용하여 양식 데이터 제출을 구현합니다. FormData는 XHR2 용으로 설계된 새로운 데이터 유형입니다. 이를 사용하여 JavaScript에서 html <form>을 실시간으로 쉽게 만들고 Ajax를 통해 양식을 제출할 수 있습니다. 위의 코드에서 제출 된 양식의 필드는 ImageFile이고 값은 Blob입니다.이 파일 Blob은 GetBlob 함수에 의해 구성되고 반환됩니다. 이 방법을 통해 파일 업로드는 간단하고 직관적입니다.
그런 다음 서버에서 사진을 받고 저장하고 업로드 된 사진의 정보를 반환합니다.
다음은 node.js 코드의 예입니다.
var q = require ( 'q'); var fs = require ( 'fs'); var path = require ( 'path'); var commidable = require ( 'commentable'); var moment = require ( 'moment'); var imageUpload = function ()}; formidable.incomingform (); form.parse (req, deferred.makenoderesolver ()); return deferred.promise;}; imageUpload.prototype.uploadimagetest = function (req) {var pathname = 'uploadimgs/dealinfo/'; var upload path = path.join pathname); return this.seformparsecallback (req) .then (function (files) {var file = files [1] .imagefile; var filetype = files [1] .imagefile.type.split ( '/') [1]; var newfilename = 'upload_' + moment (). 형식 ( 'x') + Math (Math) (). 10) + '. 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 디렉토리에 저장하고 (대중이 Express의 static의 루트 디렉토리로 설정되었다고 가정하고) 지정된 규칙에 따라 이미지의 이름을 바꾸어 업로드 된 이미지가 동일한 이름 때문에 덮어 쓰지 않도록합니다. 또한 Q는 코드에서 사용하여 콜백 기능을 사용하여 더 나은 별도의 기능 함수를 사용하여 직접 사용하지 않습니다.
위의 코드는 PC 브라우저 및 대부분의 주류 모바일 장치에서 일반적으로 작동하지만 소수의 Android 장치는 업로드 된 이미지 바이트가 0입니다. 특정 이유로 다음 웹 페이지에서 설명을 볼 수 있습니다.
그것은 이것이 Android의 버그라는 것을 의미합니다!
그래서 그것을 해결하는 방법?
실제로 답은 위의 페이지에서 찾을 수 있습니다. 즉, 파일 업로드 메소드를 변경해야합니다. XHR2에서는 Blob에 파일을 업로드하는 것 외에도 ArrayBuffer에 파일을 업로드 할 수도 있습니다.
다음은 수정 된 프론트 엔드 자바 스크립트 코드입니다.
var fileChooser = document.getElementById ( "선택"); filechooser.onchange = function () {var _this = $ (this); if (! this.files.length) return; var files = array.prototyp.slice.call (this.files); if (files.length> 1) {aller는 "upload in al al al el a. time "); return;} files.fiel.FileCH (function (file, i) {if (! /// (? : jpeg | png | gif) /i.test (file.type)) return; var reader = new FilerEader (); reader.onload = function () {var result = this.result; upload (uppord, upload). file.type);}; reader.readasdataurl (file);});}; 함수 업로드 (Basest, type) {var xhr = new xmlhttprequest (); var text = window.atob (baseStr.split ( ") [1]) [1]) [1]); var prime = 0; (var i = 0); for i = 0); text.length; i ++) {buffer [i] = text.charcodeat (i);} xhr.open ( 'post', '/uploadtest? filetype ='+type.split ( '/') [1]); xhr.setRequestheader ( 'content-type', 'application/octet-stream'); (xhr.readystate == 4 && xhr.status == 200) {var jsondata = json.parse (xhr.responsetext); console.log (jsondata);}}; // Progress 이벤트를 사용하여 진행 상황 xhr.upload.addeventListener ( 'pection', function ', function', (e) {pecent ( ') e.total)/2; // pecent를 사용하여 업로드 진행}, false); xhr.send (buffer.buffer); // ArrayBuffer에서 이미지 업로드}변경 사항을 강조하겠습니다. Arraybuffer 모드에서 이미지를 업로드하면 'Application/Octet-stream'의 요청 헤드를 추가해야합니다. 그렇지 않으면 서버가 요청에 응답 할 수 없습니다. 또한 이러한 방식으로 사진을 업로드하면 양식 데이터에서 파일 유형을 얻을 수 없습니다. 파일 유형을 쿼리 방식으로 서버로 전달할 수 있으며 서버는 파일 유형에 따라 해당 파일을 생성합니다. 다음은 소량의 수정 후 서버 코드입니다.
imageUpload.prototype.uploadimagetest = function (req) {var pathname = 'uploadimgs/dealinfo/'; var uploadpath = path.join (__ dirname, '../..../public/', pathname); return this.useformparsecallback (req) (file) {file = file; 1]. req.query.fileType? fs.createwritestream (uploadpath + newfilename); var deferred = q.defer (); readStream.pipe (readStream.pipe); readstream.on ( 'end', deferred.makenoderesolver ()); 반환 deferred.promise.then (function () {fs.unlinksync (file.path); NewFilename, filepath : '/' + pathname + newfilename, filesize : file.size/1024> 1024?수정 된 코드는 WeChat 브라우저를 포함한 Android 전화를 지원할 수 있습니다. 모든 Android 전화 가이 문제를 겪지는 않습니다. Android 전화, 특히 WeChat 브라우저에서 이미지를 업로드 할 수 없다면 위의 방법을 시도해 볼 수 있습니다.
위는 Android 휴대 전화의 WeChat 브라우저에서 XMLHTTPREQUEST 2를 사용하여 이미지를 0으로 업로드하는 솔루션입니다. 나는 그것이 모두에게 도움이되기를 바랍니다!