HTML5的File API

说到File API,比如有意思就是图片上传了。国外有一个网站叫min.us  用户只需要把图片拖到网页面中,然后自己进行排序就OK了,很方便。

下面是关于它的一段介绍视频:

目前网页上传分为三种:

1、form提交

2、flash上传

3、插件上传

各有利弊,fomr提交就是没进度条,不太好取消。flash比较难搞的就是在非ie中浏览器认为flash是新窗口会话,当前网页的cookie无法传递到flash上传工具中,而针对这个一般就是用JS把当前页面中的cookie通过flash再传给后台,而对于一个后台如果使用了统一验证身份的接口那可能会有点麻烦。第三种优势很明显,比如适合如QQ空间这样用户需要大批量上传图片的,缺点也显而易见:跨浏览器上存在问题。而HTML5中的FileReader对象与as3中的很像,只不过目前as3中的方法比这个多(有兴趣可以自己去看看adobe的lives docs,对比一下两者的区别与共同点)。

讲了这么多,回到正题:File API,拿图片上传为例(FileFileReader):

1、首先,如何控制用户单选、多选。as3中是两个不同的对象:FileReference、FileReferenceList,在as3中可以使用FileFilter过滤只允许选择的上传文件。as3中需要使用flash player 10+才支持本地预览,而且图片不易过大。

HTML5中允许选择多个文件:

<input type="file" multiple>

只允许上传一个文件:

<input  type="file" single>

2、如何让用户只能上传指定的文件格式,如上传图片组件只允许png、jpg、gif、jpeg、bmp后缀格式的图片。

我尝试着去寻找HTML5中是否也如as3中可以让开发者自定义过滤选择文件呢,结果被我找到了http://en.wikipedia.org/wiki/File_select  添加一个属性就好了accept="image/gif,image/png"

默认为“自定义文件”,如果我选择“所有文件”,所有的文件都将显示出来。

3、上传文件

这里遇到一个问题,如何获取ajax发送过去的图片信息。因为在ajax中使用的是setRequestHeader将图片信息传给后台,因为使用的nginx,无法直接获取

自定义的http-header,就修改了fastcgi-params,加了三项:

关于定义的配置规则,可以参考这一篇文章:nginx下php获取自定义请求头参数的方法

搜索了很多关于html5 upload的例子,有人用.net、ruby写了,但没有找到用php写的(有是有,不过是使用提交form至iframe的方法,不符合这里的需求),比如这个:http://valums.com/ajax-upload/ http://www.atwebresults.com/php_ajax_image_upload/

查了很久(已经很晚了,明天还得上班就不折腾了),暂时放弃php的部分,有空再写完整的例子,重点是看File、FileReader的方法(实现了本地预览的功能)

本地运行的效果:

有空再把完整的demo提供下载(暂时缺省后台php保存文件的方法),html的源码:

<!DOCTYPE html>
<html>
 <head>
  <title>File API</title>
  <meta charset="utf-8">
  <style>
#drop-area {
    height: 50px;
    line-height:50px;
    text-align: center;
    border: 2px dashed #ddd;
    padding: 10px;
    margin-bottom: 2em;
}

#drop-area .drop-instructions {
    display: block;
    height: 30px;
}

#drop-area .drop-over {
    display: none;
    font-size: 25px;
    height: 30px;
}
        
#drop-area.over {
    background: #ffffa2;
    border: 2px dashed #000;
}

#drop-area.over .drop-instructions {
    display: none;
}

#drop-area.over .drop-over {
    display: block;
}

#drop-area.over .drop-over {
    display: block;
    font-size: 25px;
}


#file-list {
    list-style: none;
    margin-bottom: 3em;
}

#file-list li {
    border-bottom: 1px solid #000;
    margin-bottom: 0.5em;
    padding-bottom: 0.5em;
}

#file-list li.no-items {
    border-bottom: none;
}

#file-list div {
    margin-bottom: 0.5em;
}

#file-list li img {
    max-width: 400px;
}

#file-list .progress-bar-container {
    width: 400px;
    height: 10px;
    border: 1px solid #555;
    margin-bottom: 20px;
}

#file-list .progress-bar-container.uploaded {
    height: auto;
    border: none;
}

#file-list .progress-bar {
    width: 0;
    height: 10px;
    font-weight: bold;
    background: #6787e3;
}

#file-list .progress-bar-container.uploaded .progress-bar{
    display: inline-block;
    width: auto;
    color: #6db508;
    background: transparent;
}
  </style>
 </head>

 <body>
  
 <section id="main-content"> 
    <h2>文件上传</h2> 
    <h3>请选择文件</h3> 
    <p> 
        <input id="files-upload" type="file" multiple accept="*.*" name="file"> 
    </p> 
    <p id="drop-area"> 
        <span class="drop-instructions">将文件拖拽到这里</span> 
        <span class="drop-over">Drop files here!</span> 
    </p> 
    
    <ul id="file-list"> 
        <li class="no-items">&nbsp;</li> 
    </ul> 
</section> 

<script>   1:     2:     !(function () {   3:         var filesUpload = document.getElementById("files-upload"),   4:             dropArea = document.getElementById("drop-area"),   5:             fileList = document.getElementById("file-list");   6:                7:         function uploadFile (file) {   8:             var li = document.createElement("li"),   9:                 div = document.createElement("div"),  10:                 img,  11:                 progressBarContainer = document.createElement("div"),  12:                 progressBar = document.createElement("div"),  13:                 reader,  14:                 xhr,  15:                 fileInfo;  16:                   17:             li.appendChild(div);  18:               19:             progressBarContainer.className = "progress-bar-container";  20:             progressBar.className = "progress-bar";  21:             progressBarContainer.appendChild(progressBar);  22:             li.appendChild(progressBarContainer);  23:               24:             /*  25:                 If the file is an image and the web browser supports FileReader,  26:                 present a preview in the file list  27:             */  28:             if (typeof FileReader !== "undefined" && (/image/i).test(file.type)) {  29:                 img = document.createElement("img");  30:                 li.appendChild(img);  31:                 reader = new FileReader();  32:                 reader.onload = (function (theImg) {  33:                     return function (evt) {  34:                         theImg.src = evt.target.result;  35:                     };  36:                 }(img));  37:                 reader.readAsDataURL(file);  38:             }  39:               40:             // Uploading - for Firefox, Google Chrome and Safari  41:             xhr = new XMLHttpRequest();  42:               43:             // Update progress bar  44:             xhr.upload.addEventListener("progress", function (evt) {  45:                 if (evt.lengthComputable) {  46:                     progressBar.style.width = (evt.loaded / evt.total) * 100 + "%";  47:                 }  48:                 else {  49:                     // No data to calculate on  50:                 }  51:             }, false);  52:               53:             // File uploaded  54:             xhr.addEventListener("load", function () {  55:                 progressBarContainer.className += " uploaded";  56:                 progressBar.innerHTML = "Loaded!";  57:             }, false);  58:               59:             xhr.open("post", "upload/upload.php", true);  60:               61:             // Set appropriate headers  62:             xhr.setRequestHeader("Content-Type", "multipart/form-data");  63:             xhr.setRequestHeader("X-File-Name", file.fileName);  64:             xhr.setRequestHeader("X-File-Size", file.fileSize);  65:             xhr.setRequestHeader("X-File-Type", file.type);  66:               67:               68:             xhr.onreadystatechange = function() {  69:                 if (xhr.readyState === 4) {  70:                     if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {  71:                         alert(xhr.responseText);  72:                         xhr = null;  73:                     }  74:                 }  75:             }  76:               77:             // Send the file (doh)  78:             if ("getAsBinary" in file) {  79:                 //FF 3.5+  80:                 xhr.sendAsBinary(file.getAsBinary());  81:             } else {  82:                 xhr.send(file);  83:             }  84:               85:               86:             // Present file info and append it to the list of files  87:             fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>";  88:             fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size / 1024, 10) + " kb</div>";  89:             fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>";  90:             div.innerHTML = fileInfo;  91:               92:             fileList.appendChild(li);  93:         }  94:           95:         function traverseFiles (files) {  96:             if (typeof files !== "undefined") {  97:                 for (var i=0, l=files.length; i<l; i++) {  98:                     uploadFile(files[i]);  99:                 } 100:             } 101:             else { 102:                 fileList.innerHTML = "No support for the File API in this web browser"; 103:             }     104:         } 105:          106:         filesUpload.addEventListener("change", function () { 107:             traverseFiles(this.files); 108:         }, false); 109:          110:         dropArea.addEventListener("dragleave", function (evt) { 111:             var target = evt.target; 112:              113:             if (target && target === dropArea) { 114:                 this.className = ""; 115:             } 116:             evt.preventDefault(); 117:             evt.stopPropagation(); 118:         }, false); 119:          120:         dropArea.addEventListener("dragenter", function (evt) { 121:             this.className = "over"; 122:             evt.preventDefault(); 123:             evt.stopPropagation(); 124:         }, false); 125:          126:         dropArea.addEventListener("dragover", function (evt) { 127:             evt.preventDefault(); 128:             evt.stopPropagation(); 129:         }, false); 130:          131:         dropArea.addEventListener("drop", function (evt) { 132:             traverseFiles(evt.dataTransfer.files); 133:             this.className = ""; 134:             evt.preventDefault(); 135:             evt.stopPropagation(); 136:         }, false);                                         137:     })();</script> 

 </body>
</html>

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术小黑屋

Atom订阅转成RSS2.0

Octopress博客自带的只Atom协议的订阅,但是最近提交收录网站时,需要使用RSS协议。于是利用周末简单实现了一下。

20820
来自专栏Bug生活2048

微信小程序版博客——图片相关处理

前面提到,小程序服务端的数据是基于Ghost的公共API的,在设计首页文章列表时,为了美观加上了头图,但是服务端没有提供对应的字段(头图url)。

40920
来自专栏小古哥的博客园

微信小程序-开发入门(一)

微信小程序已经火了一段时间了,之前一直也在关注,就这半年的发展来看,相对原生APP大部分公司还是不愿意将主营业务放到微信平台上,以免受制于腾讯,不过就小程序的应...

67650
来自专栏前端儿

教你如何在React及Redux项目中进行服务端渲染

使用 redux-saga 处理异步action,使用 express 处理页面渲染

34110
来自专栏九彩拼盘的叨叨叨

Chrome 插件收藏

Chrome 上有非常多的功能强大的和插件。这些插件让 Chrome 变得更加强大。下面是我常用的一些插件。

32910
来自专栏贾鹏辉的技术专栏@CrazyCodeBoy

React Native 混合开发(iOS篇)

在React Native的应用场景中,有时候一个APP只有部分页面是由React Native实现的,比如:我们常用的携程App,它的首页下的很多模块都是由R...

2.1K50
来自专栏coding for love

浏览器加载解析渲染机制的全面解析

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

12110
来自专栏Web 开发

新浪SAE伪域名绑定

弄完之后,再到WP4SAE里面把域名设置成自己绑定的那个域名,就实现了伪域名绑定了~

9530
来自专栏前端儿

微信小程序 - 入门指引

设置 -> 开发者设置 -> 服务器域名中   配置好服务器域名,小程序才能正确地发起异步请求

1.2K10
来自专栏王磊的博客

ReactNative开发工具有这一篇足矣

ReactNative系列文章: 1.《逻辑性最强的React Native环境搭建与调试》 2.《ReactNative开发工具有这一篇足矣》 正文 Rea...

387130

扫码关注云+社区

领取腾讯云代金券