10分钟学会文件上传
2017-07-25 15:56
169 查看
文件上传的核心就是 FileUpload 对象。在HTML文档中
每出现一次,一个FileUpload对象就会被创建。该对象包含的 value 属性保存了用户上传的文件名,并且该值是只读的,不可以被前端所修改的,当用户上传一个文件时,会触发 onchange 事件,可以以此当作钩子来操作。
在开始的时候,大家写 文件上传 功能的时候,会采用这种方法:
但是这样的弊端就是上传后被刷新了!!!
现代前端都是基于Ajax进行文件上传的
还记得Ajax怎么写么?
以上是用level1版本,现在level2版本了。
这个版本:
1,可以支持文件上传了,
2,提供了进度提示,
3,可以设置超时处理。
这样就可以通过ajax来无刷新上传文件了。
如果我们有对监听上传的进度的需求,那么需要拿到 upload 属性下面的 onprogress 方法。
onprogress 的事件回调方法中可以监听文件上传的进度,因为event下面有 loaded 和 total 属性, 前者是已上传,后者是文件总大小。 那么通过 event.loaded / event.total * 100 来拿到上传进度。
那么如何在前端展现出这个进度条呢?
HTML5为我们提供了一个 progress 标签。
这个标签是有默认样式的,如果想自定义样式,可参考 这篇文章
当然我们也可以自己通过div来模拟进度条效果,但是缺少语义化。
常规的思路是,当前端把图片提交之后,再向服务器中请求图片,但是这恐怕不算是 预览 。
已经上传了,还怎么会叫预览呢?
好在HTML5中已经支持图片预览——FileReader。
对此不熟悉的童鞋可以访问 MDN
FileReader读取的是用户本机上的图片,而不是服务器上的。
因为FileReader读取是异步的,所以这里会有几个钩子
onabort 读取操作被终止
onerror 读取操作发生错误
onload 读取操作成功完成
onloaded 读取操作完成,但不一定是成功。 可能是 onerror 也可能是 onload
onprogress 读取操作的进度
多文件支持
想让文件上传支持多文件功能, 只需:
这样就可以选择多文件上传了,但是需要注意的是,我们之前的代码逻辑都是按照单文件的逻辑来写的
如果是多文件的话,我们就需要把files文件循环添加到formData.append()里面
拖拽
样式
另一个需求是更改文件上传的默认样式
我们可以通过
然后通过设置 a 的样式来达到效果 但是点击的时候还是input的效果 所以我们直接阻止了
a 的默认效果 也可以通过 preventdefault 实现。
代码:
<input type='file'>
每出现一次,一个FileUpload对象就会被创建。该对象包含的 value 属性保存了用户上传的文件名,并且该值是只读的,不可以被前端所修改的,当用户上传一个文件时,会触发 onchange 事件,可以以此当作钩子来操作。
在开始的时候,大家写 文件上传 功能的时候,会采用这种方法:
<form action='Upload.php' method='POST' enctype='multipart/form-data'> <input type='file' name='file'></input> <button type='submit'>提交</button> </form>
但是这样的弊端就是上传后被刷新了!!!
现代前端都是基于Ajax进行文件上传的
还记得Ajax怎么写么?
var xml = new XMLHttpReques(); xml.open('POST', 'Upload.php'); xml.setRequestHeader('Content-Type', 'multipart/form-data'); xml.send(data); xml.onchange = function(){ if(xml.readyState === 4 && xml.status === 200){ console.log('success'); }else{ console.log('fail'); } }
以上是用level1版本,现在level2版本了。
这个版本:
1,可以支持文件上传了,
2,提供了进度提示,
3,可以设置超时处理。
var xhr = new XMLHttpRequest(); var formData = new FormData(); var fileInput = $("input[type='file']"); var file = fileInput.files[0]; // 第一个参数是 属性名 第二个参数是 属性值 formData.append('myFile', file); xhr.open('POST', 'Upload.php'); // 这个onload相当于level1中的 xml.readyState === 4 xhr.onload = function(){ if(this.status === 200){ console.log('s 4000 uccess') } } xhr.send(formData); xhr = null;
这样就可以通过ajax来无刷新上传文件了。
如果我们有对监听上传的进度的需求,那么需要拿到 upload 属性下面的 onprogress 方法。
onprogress 的事件回调方法中可以监听文件上传的进度,因为event下面有 loaded 和 total 属性, 前者是已上传,后者是文件总大小。 那么通过 event.loaded / event.total * 100 来拿到上传进度。
那么如何在前端展现出这个进度条呢?
HTML5为我们提供了一个 progress 标签。
<progress value='10' max='100'> </progress>
这个标签是有默认样式的,如果想自定义样式,可参考 这篇文章
当然我们也可以自己通过div来模拟进度条效果,但是缺少语义化。
图片预览
文件上传另一个重要的需求是图片预览常规的思路是,当前端把图片提交之后,再向服务器中请求图片,但是这恐怕不算是 预览 。
已经上传了,还怎么会叫预览呢?
好在HTML5中已经支持图片预览——FileReader。
对此不熟悉的童鞋可以访问 MDN
FileReader读取的是用户本机上的图片,而不是服务器上的。
因为FileReader读取是异步的,所以这里会有几个钩子
onabort 读取操作被终止
onerror 读取操作发生错误
onload 读取操作成功完成
onloaded 读取操作完成,但不一定是成功。 可能是 onerror 也可能是 onload
onprogress 读取操作的进度
function preview(){ var previewArea = $('#previewArea'); var img = docuemnt.createElement('img'); var fileInput = $('#file'); // 这里是假设只上传了一个图片 var file = fileInput.file[0]; previewArea.appendChild(img); var reader = new FileReader(); // 这个是读取的 reader.readAsDataURL(file); reader.onload = function(e){ // 这里是把图片资源转化为base64格式了 img.src = e.target.result; } }
多文件支持
想让文件上传支持多文件功能, 只需:
<input type='file' multiple>
这样就可以选择多文件上传了,但是需要注意的是,我们之前的代码逻辑都是按照单文件的逻辑来写的
如果是多文件的话,我们就需要把files文件循环添加到formData.append()里面
var fileInput = document.getElementById("myFile"); var files = fileInput.files; var formData = new FormData(); for(var i = 0; i < files.length; i++) { var file = files[i]; formData.append('files[]', file, file.name); }
拖拽
var dropArea; dropArea = document.getElementById("dropArea"); dropArea.addEventListener("dragenter", handleDragenter, false); dropArea.addEventListener("dragover", handleDragover, false); dropArea.addEventListener("drop", handleDrop, false); // 阻止dragenter和dragover的默认行为,这样才能使drop事件被触发 function handleDragenter(e) { e.stopPropagation(); e.preventDefault(); } function handleDragover(e) { e.stopPropagation(); e.preventDefault(); } function handleDrop(e) { e.stopPropagation(); e.preventDefault(); var dt = e.dataTransfer; var files = dt.files; // handle files ... }
样式
另一个需求是更改文件上传的默认样式
我们可以通过
<a href='javascript:;' class='file'>选择文件 <input type='file'> </a>
然后通过设置 a 的样式来达到效果 但是点击的时候还是input的效果 所以我们直接阻止了
a 的默认效果 也可以通过 preventdefault 实现。
代码:
.file { position: relative; display: inline-block; background: #fff; border: 1px solid #ccc; border-radius: 4px; overflow: hidden; color: #333; text-decoration: none; text-indent: 0; } .file input { position: absolute; font-size: 100px; right: 0; top: 0; opacity: 0; } .file:hover { background: #AADFFD; border-color: #78C3F3; color: #004974; text-decoration: none; }
相关文章推荐
- 10分钟学会Git教程 - 安装Git、建仓库、添加和推送文件至库
- [转]十天学会php之第十天(PHP)----学会用PHP上传文件和发邮件
- 10分钟学会Cordova的文件系统编程
- 10分钟学会Git教程 - 安装Git、建仓库、添加和推送文件至库
- 小兔Java教程 - 三分钟学会Java文件上传
- 小兔Java教程 - 三分钟学会Java文件上传
- 手把手教你学会JSP上传文件方法
- 教你五分钟学会文件上传和下载
- 10分钟学会Git教程 - 安装Git、建仓库、添加和推送文件至库
- Ajax中上传文件的方式
- SpringMVC上传文件
- PHP动态多文件上传的具体代码
- 利用Nginx的上传模块和上传进度模块实现网页上传文件
- 使用svn客户端上传文件
- 带进度条的 jQuery 文件拖放上传插件
- 如何用Java客户端/applet通过HTTP POST上传文件
- “STP主机文件上传下载工具”记录之——启动时错误“不能绑定socket,(因)地址和端口已经在使用”(1)
- .net core版 文件上传/ 支持批量上传拖拽及预览功能(bootstrap fileinput上传文件)
- 最基本图片上传及文件上传
- windows如何上传到文件linux服务器上