移动端图片操作(一)——上传

简介: 上传我们一般都是用“input[type=file]”控件。当你用此控件时,你就授权了网页和服务器访问对应的文件,就可以得到File对象。

上传我们一般都是用“input[type=file]”控件。当你用此控件时,你就授权了网页和服务器访问对应的文件,就可以得到File对象。

友情提示在,在Android手机webview中,是不支持上传文件的,网上说是修改Android端的代码,但我没试过,我们这边是使用客户端提供的接口来实现上传的。

下面的示例代码可以在这里查看到。


一、accept属性


该属性表明了服务器端可接受的文件类型,可以限制你手机选择相关的文件,如果限制多个,可以用逗号分割,下面的代码就表示只能选择图片与音频相关的文件:


<input accept="image/*,audio/*" type="file"/>


39.jpg


在移动端,点击后会让你选择拍照或相册,还是蛮高大上的。下图是UC浏览器中:


40.jpg


二、change事件


一般选择文件都会使用“change”事件,下面的代码就是绑定了change事件,弹出文件大小:

var upload = document.getElementById('upload');
upload.addEventListener('change', function() {
  var file = upload.files[0];
  alert(file.size);
}, false);


1) 有些手机浏览器在点击的时候,会弹出键盘选择,我用onfocus="this.blur()",来强制失去焦点。


<input type="file" id="upload" onfocus="this.blur()"/>


2) 当选择过一次后,再次选择同一个文件,“change”事件不会触发,因为value没有改变,在网上看到个方法,我还没有在实际项目中使用,兼容性有待考证。

使用“Node.cloneNode”复制上传元素,再用“Node.replaceChild”替换节点。

这里注意下:克隆一个元素节点会拷贝它所有的属性以及属性值,但不会拷贝那些使用addEventListener()方法或者node.onclick = fn用JavaScript动态绑定的事件。


upload.addEventListener('change', function() {
  var upload = document.getElementById('upload'); //每次要动态获取
  var file = upload.files[0];
  console.log(file.size);
  //解决上传相同文件不触发onchange事件  
  var clone = upload.cloneNode(true);
  clone.onchange = arguments.callee; //克隆不会复制动态绑定事件
  clone.value = '';
  upload.parentNode.replaceChild(clone, upload);
}, false);


三、File对象


用户所选择的文件都存储在了一个FileList对象上,其中每个文件都对应了一个File对象

File对象负责处理那些以文件形式存在的二进制数据,也就是操作本地文件。

File对象是Blob【下面会提到】的特殊类型,即大块的二进制数据,File对象的尺寸及类型等属性都继承自Blob。


1)File对象可以通过3种方式获取:


1. <input>元素上选择文件后返回的FileList对象中的成员

2. 拖放操作【Drag或Drop】生成的 DataTransfer对象内files属性中的成员

3. HTMLCanvasElement上执行mozGetAsFile()方法后的返回结果


document.getElementById('upload').files[0]//选取第一个文件对象


2)File对象有9个属性,这里就只介绍3个:


1. name:当前File对象所引用文件的文件名,不包括路径,只读。

2. size:文件大小,单位为字节,只读的64位整数.

3. type:MIME类型,只读字符串,如果类型未知,则返回null。有些移动端的浏览器明明选择了图片,返回的却是null,非常坑。

还有3个非标准的方法:getAsBinary()、getAsDataURL()和getAsText(in DOMString encoding)。

这3个方法现在已经过时,现在用FileReader对象中的方法来取代。

 

四、FileReader


web应用程序可以异步的读取存储在用户计算机上的文件(或者原始数据缓冲)内容,可以使用File对象或者Blob对象来指定所要处理的文件或数据。

1) readAsArrayBuffer():在返回的result属性中将包含一个ArrayBuffer对象【缓冲数组,是一种用于呈现通用、固定长度的二进制数据的类型】以表示所读取文件的内容

Blob可以“append”,ArrayBuffer数据。ArrayBuffer存在的意义就是作为数据源提前写入在内存中,就是提前钉死在某个区域,长度也固定。

2) readAsBinaryString():result属性中将包含所读取文件的原始二进制数据

3) readAsDataURL():result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容

4) readAsText():result属性中将包含一个字符串以表示所读取的文件内容

下面的代码是获取data:URL,可以将返回的result内容赋值给img的src,用于预览等操作。

var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
  var img = new Image();
  img.src = this.result;
  console.log(this.result);
};


console.log(this.result)内容如下:


41.jpg


五、URL对象


URL对象是硬盘上指向文件的URL。上面的例子中获取图片的引用,通过读取data URI,data URI是个一大串的字符。

图片原本就在硬盘上,还要转换成另一个格式再用,有点绕了,完全可以直接引用文件的URL,下面是两个方法:

1) URL.createObjectURL():接收一个文件的引用(File或Blob对象)返回一个URL对象

2) URL.revokeObjectURL():销毁创建的URL


var url = URL.createObjectURL(file);
var img = new Image();
img.src = url;
img.onload = function(e) {
  window.URL.revokeObjectURL(this.src); //销毁
}
console.log(url);


console.log(url)内容如下:


42.jpg

在移动端需要做个兼容性判断:


window.URL = window.URL || window.webkitURL;


六、Blob对象


Blob(binary large object)对象代表了一段二进制数据,就是一个包含只读原始数据的类文件对象。

File接口基于Blob,继承了Blob的功能,并且扩展支持了用户计算机上的本地文件。


1)创建Blob对象的4种方法:


1. 调用Blob构造函数

2. 使用一个已有Blob对象上的slice()方法切出另一个Blob对象

3. 调用canvas对象上的toBlob方法

4. 过气的方法,通过BlobBuilder接口创建,但兼容性不好,并且现有的BlobBuilder实现都是带前缀的

 

2)利用Blob对象,生成可下载文件

var blob = new Blob(["pwstrick"]);//数组中添加DOMString对象
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);//创建URL对象
a.download = "test.txt";//HTML5新属性
a.textContent = "test";            
document.getElementsByTagName('body')[0].appendChild(a);


生成一个“a”标签,并且点击这个链接,可以下载一个txt文本,内容是“pwstrick”。

 

3)通过slice方法,将二进制数据按照字节分块,返回一个新的Blob对象


upload.addEventListener('change', function() {
  var upload = document.getElementById('upload'); //每次要动态获取
  var file = upload.files[0];
  var start = 0;
  var chunk = 1024 * 10; //10KB
  var end = start + chunk;
  var size = file.size;
  while (start < size) {
    segment(file, start, end);
    start = end;
    end = start + chunk;
    if (end > size) {
      end = size;
    }
  }
}, false);
function segment(file, start, end) {
  var reader = new FileReader();
  reader.onload = function(evt) {
    console.log(['Read bytes: ', start, ' - ', end].join(''));
  };
  var blob = file.slice(start, end);
  reader.readAsBinaryString(blob);
}


七、formData


XMLHttpRequest Level 2添加了一个新的接口FormData

利用FormData对象,可以使用键值对来模拟一个完整的表单,然后使用XMLHttpRequest发送这个"表单"。

使用FormData的最大优点就是我们可以异步上传一个二进制文件。

var formData = new FormData();
  formData.append("name", "value");//普通键值对
  formData.append("blob", blob); //传递一个blob对象
  formData.append("file", file); //传递一个file对象
  var oReq = new XMLHttpRequest();
  oReq.open("POST", "http://xx.com");
  oReq.send(formData);



相关文章
针对FastAdmin新增上传多个图片,新增上传的视频的预览效果
针对FastAdmin新增上传多个图片,新增上传的视频的预览效果
852 0
|
小程序 JavaScript 数据库
微信小程序系列——上传下载图片以及图片的展示
微信小程序系列——上传下载图片以及图片的展示
|
6月前
|
前端开发
前端实现视频或者图片直链下载
前端实现视频或者图片直链下载
236 0
|
12月前
|
前端开发 JavaScript
uniapp上传图片至服务器,获得在线图片链接预览(实战)
uniapp上传图片至服务器,获得在线图片链接预览(实战)
439 0
|
存储 小程序 JavaScript
小程序云开发上传及使用图片
小程序云开发上传及使用图片
139 0
|
前端开发
织梦dedecms评论助手插件(支持图片视频上传与随机头像功能)
织梦评论助手是一款评论插件,安装后可以替代原有的织梦评论,立即拥有一个属于你自己网站的友好的评论系统。支持评论图片视频上传与评论者随机头像功能。
|
前端开发
后端处理图片的上传和下载
后端处理图片的上传和下载
166 0
|
移动开发 JSON 前端开发
前端H5选图预览到上传
在金融性质的App里,选择本地相册图片或者拍照,然后预览并且上传是一个典型的使用场景,比如常见的身份证信息上传。在最近接触的几家银行客户里,都反馈有类似的场景,并且在使用上都或多或少的遇到一些问题,最后找到我们,希望我们提供一些最佳实践。在这里分享下对应场景的一些优化解决方案。
401 0
前端H5选图预览到上传
|
JavaScript
原生js实现图片单张上传及批量上传
原生js实现图片单张上传及批量上传
|
前端开发 HTML5 移动开发
移动端图片上传旋转、压缩的解决方案
在手机上通过网页 input 标签拍照上传图片,有一些手机会出现图片旋转了90度d的问题,包括 iPhone 和个别三星手机。这些手机竖着拍的时候才会出现这种问题,横拍出来的照片就正常显示。
1283 0