web 文件上传的几种方式
问题
文件上传在WEB开发中应用很广泛。
文件上传是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。
以下总结了常见的文件(图片)上传的方式和要点处理。
表单上传
这是传统的form表单上传,使用form表单的input[type=”file”]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,它是web开发者最常用的一种文件上传方式。
表单的代码如下:
<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>
以下是表单上传几个关键点:
method="post"
: 采用post方式提交数据enctype="multipart/form- data"
:采用multipart格式上传文件,此时request头会显示 Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryzr34cwJ67R95KQC9action
:标明上传的服务端处理地址type="file"
:使用input的file控件上传
如果是多文件批量上传,可以将input[type=”file”]的name属性设置为如:name=”file[]”accept
属性是HTML5的新属性,它规定了可通过文件
上传提交的文件类型
上传的触发事件可以是:input[type=”file”]的onChange
触发,也可以由一个独立的按钮的onClick
使整个表单提交,此时还可以用input[type="hidden"]
带一些其它的参数,比如Token来源验证等等。
Ajax无刷新上传
Ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果,不用像直接表单上传那样刷新和跳转页面。在这里,我们采用jQuery来作为操作DOM和创建ajax提交的js基础库。
html代码片段如下:
1
2
3
4
|
< form > < input id="file" name="file" type="file" /> < input id="token" name="token" type="hidden" /> </ form > |
javascript代码片段如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
$( "#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
实例的参数提交给服务端。
使用jQuery提供的ajax方法来发送二进制文件,还需要附加两个参数:
processData
: false // 不要对data参数进行序列化处理,默认为truecontentType
: false // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码
Flash上传
很多时候上传的需求要求显示上传进度、中断上传过程、大文件分片上传等等,这时传统的表单上传很难实现这些功能,于是产生了使用Flash上传的方式,它采用Flash作为一个中间代理层,代替客户端跟服务端通信,此外,它也对客户端的文件选择方面拥有更多的控制权,比input[type=”file”] 要大得多。
在这里我使用了jQuery封装好的uploadify
插件来进行演示,一般这类插件都自带了上传用的Flash文件,因为跟服务端回传的数据和展示跟客户端的交互,都是Flash文件的接口跟插件来对接的。
<div id="file_upload"></div>
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){ // 根据返回结果指定界面操作 } }); });
关于jQuery.uploadify可以访问了解: http://www.uploadify.com/documentation/ 。值得注意的是flash并不适合手机端应用,更好的解决方案是使用flash+html5来解决平台的兼容性问题。
截图粘贴上传
我们发现现在有好多上传应用已经提供了截图粘贴上传功能,如WebUploader
,它就支持QQ截图然后粘贴上传。
首先,截图粘贴上传的核心思想是,监听粘贴事件,然后获取剪切板中的数据,如果是一张图片,则触发上传事件。
代码片段如下:
$("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’,从系统剪切板获取内容,而系统剪切板的数据在不同浏览器保存在不同的位置:
IE内核:windows.clipboardData
其它:e.originalEvent.clipboardData
拖拽上传
拖拽上传的方式,支持的浏览器比较少,因为它用到了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” 等。
代码片段如下:
// 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); }); });
拖拽上传过程中的几个关键点:
在drop事件触发后通过e.dataTransfer.files获取拖拽文件列表,在jQuery中是e.originalEvent.dataTransfer.files
拖拽上传仅支持图片,文件对象中file.type标识了文件类型。
由于可能是多图拖拽,所以可以遍历图片上传,这里用了Underscore的each方法。
这里用readAsDataURL读取文件内容为二进制文件,你还可以将其转换为Base64方式上传,只是http协议里面存在对非二进制数据的上传大小限制为2M。
上传的过程跟前面的方式相同,即:创建FormData对象并发起Ajax请求。
拍照上传
拍照上传可以是PC上的摄像头拍照上传也可以是手机等移动设备的拍照上传。手机上的拍照上传最常见就是我们使用微信发照片了。
手机实现拍照上传的代码:
<input type=file accept="image/*">
<input type=file accept="video/*">
ios 有拍照、录像、选取本地图片功能,部分android只有选取本地图片功能。
上传与安全
上传文件时必须做好文件的安全性,除了前端必要的验证,如文件类型、后缀、大小等验证,重要的还是要在后台做安全策略。
这里我列举几个注意点:
- 后台需要进行文件类型、大小、来源等验证
- 定义一个.htaccess文件,只允许访问指定扩展名的文件。
- 将上传后的文件生成一个随机的文件名,并且加上此前生成的文件扩展名。
- 设置上传目录执行权限,避免不怀好意的人绕过如图片扩展名进行恶意攻击,拒绝脚本执行的可能性。
web 文件上传的几种方式的更多相关文章
- curl文件上传有两种方式,一种是post_fileds,一种是infile
curl文件上传有两种方式,一种是POSTFIELDS,一种是INFILE,POSTFIELDS传递@实际地址,INFILE传递文件流句柄! );curl_setopt($ch, CURLOPT_PO ...
- Java文件上传的几种方式
文件上传与文件上传一样重要.在Java中,要实现文件上传,可以有两种方式: 1.通过Servlet类上传 2.通过Struts框架实现上传 这两种方式的根本还是通过Servlet进行IO流的操作. 一 ...
- 利用Selenium实现图片文件上传的两种方式介绍
在实现UI自动化测试过程中,有一类需求是实现图片上传,这种需求根据开发的实现方式,UI的实现方式也会不同. 一.直接利用Selenium实现 这种方式是最简单的一种实现方式,但是依赖于开发的实现. 当 ...
- C#实现Web文件上传的两种方法
1. C#实现Web文件的上传 在Web编程中,我们常需要把一些本地文件上传到Web服务器上,上传后,用户可以通过浏览器方便地浏览这些文件,应用十分广泛. 那么使用C#如何实现文件上传的功能呢?下面笔 ...
- Python菜鸟之路:Django 文件上传的几种方式
方式一:通过form表单中,html input 标签的“file”完成 # 前端代码uoload.html <form method="post" action=" ...
- Servlet中文件上传的几种方式
上传文件,因为上传的都是二进制数据,所以在Servlet中就不能直接用request.getParameter();方法进行数据的获取,需要借助第三方jar包对上传的二进制文件进行解析.常用的方式如下 ...
- ajax以及文件上传的几种方式
方式一:通过form表单中,html input 标签的“file”完成 # 前端代码uoload.html <form method="post" action=" ...
- python文件上传的三种方式
def upload(request): return render(request, 'upload.html') def upload_file(request): username = requ ...
- ASP.NET Core 1.0中实现文件上传的两种方式(提交表单和采用AJAX)
Bipin Joshi (http://www.binaryintellect.net/articles/f1cee257-378a-42c1-9f2f-075a3aed1d98.aspx) Uplo ...
随机推荐
- python爬百度文库课件
库:re;selenium;requests 源码: from selenium import webdriverimport reimport requests def open_img(items ...
- py3,休息时间玩点小把戏
100以内奇数: ls = [x for x in range(100) if x % 2 == 1] 100以内偶数: ls = list(x for x in range(100) if x % ...
- jquery选择器问题(找东西超级有用)
$("[class='slider-container theme-green']").css('width','100%');就这么一行代码,很简单,这样就很容易找到唯一元素
- JAVA Freemarker + Word 模板 生成 Word 文档 (普通的变量替换,数据的循环,表格数据的循环,以及图片的东替换)
1,最近有个需求,动态生成 Word 文当并供前端下载,网上找了一下,发现基本都是用 word 生成 xml 然后用模板替换变量的方式 1.1,这种方式虽然可行,但是生成的 xml 是在是太乱了,整理 ...
- NamedParameterJdbcTemplate
NamedParameterJdbcTemplate 在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参 ...
- Tomcat源码分析 -- Tomcat整体架构
引用链接:https://blog.csdn.net/w1992wishes/article/details/79242797
- js中this的绑定规则及优先级
一. this绑定规则 函数调用位置决定了this的绑定对象,必须找到正确的调用位置判断需要应用下面四条规则中的哪一条. 1.1 默认绑定 看下面代码: function foo() { cons ...
- dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js` vue启动报错解决
这是因为webpack-dev-server版本和vue版本不一样,需要将webpack-dev-server卸载了,安装对应版本 查看vue版本是 vue -V 注意:V是大写 卸载npm unin ...
- rem_750
/* fix the code flash the page */ var globalWidth = document.documentElement.clientWidth;//window.in ...
- GIS案例学习笔记-三维生成和可视化表达
GIS案例学习笔记-三维生成和可视化表达 联系方式:谢老师,135-4855-4328,xiexiaokui#qq.com 目的:针对栅格或者矢量数值型数据,进行三维可视化表达 操作时间:15分钟 案 ...