前端JS中使用XMLHttpRequest 2上传图片到服务器,PC端和大部分手机上都正常,但在少部分安卓手机上上传失败,服务器上查看图片,显示字节数为0。下面是上传图片的核心代码:
HTML
<input type="file" id="choose" capture="camera" accept="image/*"> JavaScript var filechooser = document.getElementById("choose"); filechooser.onchange = function () { var _this = $(this); if (!this.files.length) return; var files = Array.prototype.slice.call(this.files); if (files.length > 1) { alert("一次只能上传1张图片"); return; } files.forEach(function (file, i) { if (!/\/(",")[1]); var buffer = new Uint8Array(text.length); var pecent = 0; for (var i = 0; i < 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'); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var jsonData = JSON.parse(xhr.responseText); console.log(jsonData); } }; //利用progress事件显示数据发送进度 xhr.upload.addEventListener('progress', function (e) { pecent = ~~(100 * e.loaded / e.total) / 2; // 利用pecent来显示上传进度 }, false); xhr.send(formdata); } function getBlob(buffer, format){ 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,这是一个通过getBlob函数构造并返回的文件Blob。通过该方法上传文件简单直观。
然后我们在服务端接收并保存图片,并返回已上传的图片的信息。
下面是Node.js代码的示例:
var Q = require('q'); var fs = require('fs'); var path = require('path'); var formidable = require('formidable'); var moment = require('moment');var imageUpload = function (){ }; imageUpload.prototype.useFormParseCallback = function(req){ var deferred = Q.defer(); var form = new formidable.IncomingForm(); form.parse(req, deferred.makeNodeResolver()); return deferred.promise; }; imageUpload.prototype.uploadImageTest = function(req){ var pathName = 'uploadImgs/dealInfo/'; var uploadPath = path.join(__dirname, '../../public/', pathName); return this.useFormParseCallback(req).then(function(files){ var file = files[1].imagefile; var fileType = files[1].imagefile.type.split('/')[1]; var newFileName = 'upload_' + moment().format('x') + Math.random().toString().substr(2, 10) + '.' + fileType; var readStream = fs.createReadStream(file.path); var writeStream = fs.createWriteStream(uploadPath + newFileName); var deferred = Q.defer(); readStream.pipe(writeStream); readStream.on('end', deferred.makeNodeResolver()); return deferred.promise.then(function() { fs.unlinkSync(file.path); return { fileName: newFileName, filePath: '/' + pathName + newFileName, fileSize: file.size/1024 > 1024 "MB" : ~~(file.size/1024) + "KB" }; }); }); }; module.exports = imageUpload;
我们使用formidable这个包来接收上传文件的数据,然后将文件保存到/public/uploadImgs/dealInfo目录下(假定已在express中将public设置为static的根目录),并将图片按照指定的规则重命名,以保证上传图片不会因为名称相同而被覆盖。另外,代码中使用Q来避免直接使用回调函数,以更好地对函数功能进行分离。
上面的代码在PC端浏览器以及大部分主流移动设备上都能正常工作,但是少部分Android设备上却会出现上传的图片字节数为0的情况。具体的原因大家可以看下面几个网页中的描述:
就是说这个是Android的一个bug!
那如何解决呢?
其实从上面给出的页面中可以找到答案,就是我们得换一种文件上传方式。在XHR2中,除了以Blob的方式上传文件外,还可以ArrayBuffer的方式上传文件。
下面是修改之后的前端JavaScript代码:
var filechooser = document.getElementById("choose"); filechooser.onchange = function () { var _this = $(this); if (!this.files.length) return; var files = Array.prototype.slice.call(this.files); if (files.length > 1) { alert("一次只能上传1张图片"); return; } files.forEach(function (file, i) { if (!/\/(",")[1]); var buffer = new Uint8Array(text.length); var pecent = 0; for (var i = 0; i < text.length; i++) { buffer[i] = text.charCodeAt(i); } xhr.open('post', '/uploadtest"htmlcode">imageUpload.prototype.uploadImageTest = function(req){ var pathName = 'uploadImgs/dealInfo/'; var uploadPath = path.join(__dirname, '../../public/', pathName); return this.useFormParseCallback(req).then(function(files){ var file = files[1].file; var fileType = req.query.filetype "MB" : ~~(file.size/1024) + "KB" }; }); }); };修改之后的代码可以支持Android手机,包括微信浏览器。注意不是所有的Android手机都会存在该问题,如果你发现在Andriod手机上无法上传图片,尤其是在微信浏览器中,则可以尝试下上面的方法。
以上所述是小编给大家介绍的关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法,希望对大家有所帮助!
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。