We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tags: 图片上传, multipart, 截图上传, file对象, FormData, 拖拽上传图片, dataTransfer, readAsDataURL
一个如下所示的发布框,经常会出现在各种微博、社区、论坛站点上,这类发布形式虽然没有高级编辑器那样可以任意排版加工,但也满足了常见的表述观点意见的要求,它通常搭配一些表情、文件上传、分享网页视频等方式,来满足上述需求。最近我从事的一个项目中,就完成了如下图示的发布内容的需求,今天主要讲一下其中图片和附件的上传发布方式。
其实上传的方式有很多种,本文将列举需求中用到的几种上传方式。
也就是用传统的form表单来上传,使用form表单的input[type="file"]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,但是在多图上传、分段上传上等高级特性上就显得力不从心。
表单的格式如下:
<form method="post" action="http://uploadUrl" enctype="multipart/form-data"> <input name="file" type="file" accept="image/gif,image.jpg" /> <input name="token" type="hidden" /> <input type="submit" value="提交" /> </form>
我列出表单上传所需的关键几点:
ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果,不用像直接表单上传那样刷新和跳转页面。在这里,我们采用jQuery来作为操作DOM和创建ajax提交的js基础库。
html代码片段如下:
<form> <input id="file" name="file" type="file" /> <input id="token" name="token" type="hidden" /> </form>
javascript代码片段如下:
$("#file").on("change", function(){ var formData = new FormData(); formData.append("file", $("#file")[0].files); formData.append("token", $("#token").val()); $.ajax({ url: "http://uploadUrl", type: "POST", data: formData, processData: false, contentType: false, success: function(response){ // 根据返回结果指定界面操作 } }); });
我们使用了file控件的change来触发上传事件,当然你也可以使用某个按钮来触发表单提交。提交数据时,我用到了FormData对象来发送二进制文件,FormData构造函数提供的append()方法,除了直接添加二进制文件还可以附带一些其它的参数,作为XMLHttpRequest实例的参数提交给服务端。
如下是Firefox MDN对FormData的解释。
XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件. https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
BTW: 使用jQuery提供的ajax方法来发送二进制文件,还需要附加两个参数:
很多时候上传的需求都不是只局限于单图上传,而且需要显示上传进度、中断上传过程、大文件分段上传等等,这时传统的表单上传无法实现这些功能,于是产生了使用Flash上传的方式,它采用Flash作为一个中间代理层,代替客户端跟服务端通信,此外,它也对客户端的文件选择方面拥有更多的控制权,比input[type="file"]要大得多。
在这里我使用了jQuery封装好的uploadify插件来进行演示,一般这类插件都自带了上传用的Flash文件,因为跟服务端回传的数据和展示跟客户端的交互,都是Flash文件的接口跟插件来对接的。
<div id="file_upload">
html部分很简单,预留一个hook后,插件会在这个节点内部创建Flash的object,并且还附带创建了上传进度、取消控件和多文件队列展示等界面。
$(function() { $("#file_upload").uploadify({ auto: true, method: "Post", width: 120, height: 30, swf: './uploadify.swf', uploader: 'http://uploadUrl', formData: { token: $("#token").val() }, fileObjName: "file", onUploadSuccess: function(file, data, response){ // 根据返回结果指定界面操作 } }); });
选择一个文件后,html代码如下所示:
<!--上传Flash--> <div id="file_upload" class="uploadify" style="height: 30px; width: 120px;"> <object id="SWFUpload_0" type="application/x-shockwave-flash" data="./uploadify.swf?preventswfcaching=1463109060389" width="120" height="30" class="swfupload" style="position: absolute; z-index: 1;"> <param name="wmode" value="transparent"> <param name="movie" value="./uploadify.swf?preventswfcaching=1463109060389"> <param name="quality" value="high"> <param name="menu" value="false"> <param name="allowScriptAccess" value="always"> <param name="flashvars" value="..."> </object> <div id="file_upload-button" class="uploadify-button " style="height: 30px; line-height: 30px; width: 120px;"> <span class="uploadify-button-text">SELECT FILES</span> </div> </div> <!--上传队列和文件操作、进度展示--> <div id="file_upload-queue" class="uploadify-queue"> <div id="SWFUpload_0_0" class="uploadify-queue-item"> <div class="cancel"> <a href="javascript:$('#file_upload').uploadify('cancel', 'SWFUpload_0_0')">X</a> </div> <span class="fileName">1111111.png (144KB)</span> <span class="data"></span> <div class="uploadify-progress"> <div class="uploadify-progress-bar"><!--Progress Bar--></div> </div> </div> </div>
更多的API和配置请参考jQuery.uploadify 官网APIs 美中不足的是,mac下会对Flash有各种各样的限制,甚至不支持,所以使用的时候也要慎重考虑。
目前只有较大的几家SNS和微博类型的站点发布框实现了这个功能,本着业界良心和用户至上的原则,我们也在内外站点开发的早期上线了此功能,此次只是对上传接口的改造,在这里简单的把上传过程和用到的内容介绍一下。
首先,截图粘贴上传的核心思想是,监听粘贴事件,然后获取剪切板中的数据,如果是一张图片,则触发上传事件。 代码片段如下:
$("textarea").on("paste", function(e){ e.stopPropagation(); var self = this; var clipboardData = e.originalEvent.clipboardData; if (clipboardData.items.length <= 0) { return; } var file = clipboardData.items[0].getAsFile(); if (!file) { return; } var formData = new FormData(); formData.append("file", file); formData.append("token", $("#token").val()); $.ajax({ url: "http://uploadUrl", type: "POST", data: formData, }).done(function(response) { // 根据返回结果指定界面操作 }); e.preventDefault(); });
从上面代码可以看出,上传的过程都是一样的,主要是获取文件的方式。 当进行粘贴(右键paste/ctrl+v)操作时,触发剪贴板事件'paste',从系统剪切板获取内容,而系统剪切板的数据在不同浏览器保存在不同的位置:
https://www.w3.org/TR/clipboard-apis/
拖拽上传的方式,支持的浏览器比较少,因为它用到了HTML5的两个新的属性(API)一个是Drag and Drop,一个是File API
上传域监听拖拽的三个事件:dragEnter、dragOver和drop,分别对应拖拽至、拖拽时和释放三个操作的处理机制,当然你也可以监听dragLeave事件。
HTML5的File API提供了一个FileList的接口,它可以通过拖拽事件的e.dataTransfer.files来传递的文件信息,获取本地文件列表信息。
File API在HTML5规范中只是草案,在 W3C 草案中,File 对象只包含文件名、文件类型和文件大小等只读属性。但部分浏览器�在草案之外提供了一个名为 FileReader 的对象,用以读取文件内容,并且可以监控读取状态,它提供的方法有: "readAsBinaryString" ,"readAsDataURL" ,"readAsText" ,"abort" 等。
参考MDN https://developer.mozilla.org/en-US/docs/Web/API/File
代码片段如下:
// dragenter $("#textarea").on("dragenter", function(e){ e.preventDefault(); }); // dragover $("#textarea").on("dragover", function(e){ e.preventDefault(); }); // drop $("#textarea").on("drop", function(e){ e.stopPropagation(); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; _.each(files, function(file) { if (!/^image*/.test(file.type)) { return; } var fileReader = new FileReader(); fileReader.onload = function() { //uploadFile(file); }; fileReader.readAsDataURL(file); }); });
拖拽上传过程中的几个关键点:
The text was updated successfully, but these errors were encountered:
No branches or pull requests
一个如下所示的发布框,经常会出现在各种微博、社区、论坛站点上,这类发布形式虽然没有高级编辑器那样可以任意排版加工,但也满足了常见的表述观点意见的要求,它通常搭配一些表情、文件上传、分享网页视频等方式,来满足上述需求。最近我从事的一个项目中,就完成了如下图示的发布内容的需求,今天主要讲一下其中图片和附件的上传发布方式。
其实上传的方式有很多种,本文将列举需求中用到的几种上传方式。
1. 表单上传
也就是用传统的form表单来上传,使用form表单的input[type="file"]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,但是在多图上传、分段上传上等高级特性上就显得力不从心。
表单的格式如下:
我列出表单上传所需的关键几点:
2. Ajax无刷新上传
ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果,不用像直接表单上传那样刷新和跳转页面。在这里,我们采用jQuery来作为操作DOM和创建ajax提交的js基础库。
html代码片段如下:
javascript代码片段如下:
我们使用了file控件的change来触发上传事件,当然你也可以使用某个按钮来触发表单提交。提交数据时,我用到了FormData对象来发送二进制文件,FormData构造函数提供的append()方法,除了直接添加二进制文件还可以附带一些其它的参数,作为XMLHttpRequest实例的参数提交给服务端。
如下是Firefox MDN对FormData的解释。
BTW: 使用jQuery提供的ajax方法来发送二进制文件,还需要附加两个参数:
3. flash上传
很多时候上传的需求都不是只局限于单图上传,而且需要显示上传进度、中断上传过程、大文件分段上传等等,这时传统的表单上传无法实现这些功能,于是产生了使用Flash上传的方式,它采用Flash作为一个中间代理层,代替客户端跟服务端通信,此外,它也对客户端的文件选择方面拥有更多的控制权,比input[type="file"]要大得多。
在这里我使用了jQuery封装好的uploadify插件来进行演示,一般这类插件都自带了上传用的Flash文件,因为跟服务端回传的数据和展示跟客户端的交互,都是Flash文件的接口跟插件来对接的。
html部分很简单,预留一个hook后,插件会在这个节点内部创建Flash的object,并且还附带创建了上传进度、取消控件和多文件队列展示等界面。
选择一个文件后,html代码如下所示:
4. 截图粘贴上传
目前只有较大的几家SNS和微博类型的站点发布框实现了这个功能,本着业界良心和用户至上的原则,我们也在内外站点开发的早期上线了此功能,此次只是对上传接口的改造,在这里简单的把上传过程和用到的内容介绍一下。
首先,截图粘贴上传的核心思想是,监听粘贴事件,然后获取剪切板中的数据,如果是一张图片,则触发上传事件。
代码片段如下:
从上面代码可以看出,上传的过程都是一样的,主要是获取文件的方式。
当进行粘贴(右键paste/ctrl+v)操作时,触发剪贴板事件'paste',从系统剪切板获取内容,而系统剪切板的数据在不同浏览器保存在不同的位置:
5. 拖拽上传
拖拽上传的方式,支持的浏览器比较少,因为它用到了HTML5的两个新的属性(API)一个是Drag and Drop,一个是File API
上传域监听拖拽的三个事件:dragEnter、dragOver和drop,分别对应拖拽至、拖拽时和释放三个操作的处理机制,当然你也可以监听dragLeave事件。
HTML5的File API提供了一个FileList的接口,它可以通过拖拽事件的e.dataTransfer.files来传递的文件信息,获取本地文件列表信息。
File API在HTML5规范中只是草案,在 W3C 草案中,File 对象只包含文件名、文件类型和文件大小等只读属性。但部分浏览器�在草案之外提供了一个名为 FileReader 的对象,用以读取文件内容,并且可以监控读取状态,它提供的方法有: "readAsBinaryString" ,"readAsDataURL" ,"readAsText" ,"abort" 等。
代码片段如下:
拖拽上传过程中的几个关键点:
总结
The text was updated successfully, but these errors were encountered: