Web文件上传方法总结大全
上传文件与与上传数据区别
上传数据主要指json等简单字符串,上传文件指的是上传word、excel图片等。在上传数据的时候enctype默认为第一个application/x-www-form-urlencoded,而上传数据包含文件的时候要用第二种multipart/form-data
值 | 描述 |
---|---|
application/x-www-form-urlencoded | 在发送前编码所有字符(默认)url编码 |
multipart/form-data | 不对字符编码。 在使用包含文件上传控件的表单时,必须使用该值。 |
text/plain | 空格转换为 "+" 加号,但不对特殊字符编码。 |
文件上传在WEB开发中应用很广泛,我们经常发微博、发微信朋友圈都用到了图片上传功能。
文件上传是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。
今天我给大家聊聊常见的文件(图片)上传的方式和要点处理。
表单上传
这是传统的form表单上传,使用form表单的input[type=”file”]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,它是web开发者最常用的一种文件上传方式。
表单的代码如下:
<formmethod="post"action="http://uploadUrl"enctype="multipart/form-data">
<inputname="file"type="file"accept="image/gif,image.jpg"/>
<inputname="token"type="hidden"/>
<inputtype="submit"value="提交"/>
</form>
以下是表单上传几个关键点:
- method=”post”: 采用post方式提交数据
- enctype=”multipart/form- data”:采用multipart格式上传文件,此时request头会显示 Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryzr34cwJ67R95KQC9
- action:标明上传的服务端处理地址
- 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代码片段如下:
<form>
<inputid="file"name="file"type="file"/>
<inputid="token"name="token"type="hidden"/>
</form>
javascript代码片段如下:
$("#file").on("change",function(){
var formData =newFormData();
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参数进行序列化处理,默认为true
- contentType: false // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码
表单上传和ajax上传实质是一样的,只不过表单上传已经封装好了,比较浅显,ajax比较容易控制
上传与安全
上传文件时必须做好文件的安全性,除了前端必要的验证,如文件类型、后缀、大小等验证,重要的还是要在后台做安全策略。
这里我列举几个注意点:
- 后台需要进行文件类型、大小、来源等验证
- 定义一个.htaccess文件,只允许访问指定扩展名的文件。
- 将上传后的文件生成一个随机的文件名,并且加上此前生成的文件扩展名。
- 设置上传目录执行权限,避免不怀好意的人绕过如图片扩展名进行恶意攻击,拒绝脚本执行的可能性。