很多项目中都需要有文件上传的功能,一般文件上传有几种方式,input file表单上传,flash上传。
flash就不说了,能接受flash的就用吧。
下面介绍的这种是基于input file控件的无刷新上传文件方案。
一般上传是用iframe表单提交的方式,页面中的iframe刷新是不会刷新整个页面的,所以由iframe利用input file提交表单上传到服务器在主页面看起来就是无刷新的。
大家能想到的方法无外乎:
1.在页面新建一个iframe和一个form
2.form的target指向iframe
3.form中新建一个input file
4.点击form中的input选择文件之后提交form实现上传,返回上传到服务器的文件地址,获取到地址返回到主页面(注意:IE中必须由用户自己点击input才能提交form。否则报拒绝访问的错误)
5.主页面获得地址展示
这里有一个小小的问题用户必须自己点击input选择文件才能提交!(只有IE会有问题,但是这是不能忽视的)也就是说让用户点击的input嵌套在一个form中。
form与主页面之间还要做各种交互。
这无论对于按钮布局样式还是程序便捷性都是不好的。
然后我去网站找了很多很优秀的上传插件,不是说不好,一是我觉得太重量级,二是自定义程度不高,第三个原因呢不知道是不是我太笨的缘故 教程看不懂啊!没有很好的demo也是造成很多使用者的困扰!索性自己写一个吧。
基本原理就是上述的那样 做了以下调整:
在主页面中添加input由用户去点击选择文件,input的change事件把input本身复制到form中并提交form,iframe的load事件得到返回的地址之后回调方法。
然后方法做了一些优化方便使用者调用
/* 通用文件上传类 version 1.00 code by chenfeng during 2014年6月5日 link zhaoyunfei9271@163.com Demo: $("#filepost1").Uploader({////上传控件的ID action: "/ajax/uploaderajax.ashx",//上传到服务器的路径 默认:/ajax/uploaderajax.ashx params: "action=uploadpic",//特殊参数 随同文件一起提交到后台,以&号分隔 默认:action=uploadpic maxsize: 1024 * 500,//文件最大尺寸 默认:500K exts: ".jpg|.png|.gif|.jpeg",//文件格式限制 默认:.jpg|.png|.gif|.jpeg callback: function (file, urlpath) { //上传完成之后回调函数 返回 控件实例和文件服务器路径 } }); */ $(function () { var Uploader = function (file, options) { var defaults = { action: "/ajax/uploaderajax.ashx", params: "action=uploadpic", maxsize: 1024 * 500, exts: ".jpg|.png|.gif|.jpeg", callback: function (fileid, urlpath) { } }; if (options == "remove") { Uploader.Remove(file); return; } var opts = $.extend(defaults, options); var params = opts.params.split("&"); var form = $(‘<form action="‘ + opts.action + ‘" enctype="multipart/form-data" method="post" target="ifr_‘ + $(file).attr("id") + ‘" name="form_‘ + $(file).attr("id") + ‘" id="form_‘ + $(file).attr("id") + ‘" style="display: none;"/>‘); for (var i = 0; i < params.length; i++) { var values = params[i].split("="); $(form).append(‘<input type="hidden" name="‘ + values[0] + ‘" value="‘ + values[1] + ‘"/>‘); } var iframe = $(‘<iframe name="ifr_‘ + $(file).attr("id") + ‘" id="ifr_‘ + $(file).attr("id") + ‘" style="position: absolute; top: -999px;"></iframe>‘); $(file).change(function (e) { if ($(this).val() != "" && $(this) != undefined) { if (!Uploader.BeforeCheck(file, opts)) { return; } var pfile = $(this).parent(); $(form).append($(this)); $(form).submit(); $(pfile).append($(this)); } }); $(iframe).load(function () { var contents = $(this).contents().get(0); var data = $(contents).find(‘body‘).html(); if (data == "") { return; } data = window.eval(‘(‘ + data + ‘)‘); if (data.code != 200) { alert(data.message); return; } var picUrl = data.data.path; opts.callback(file, picUrl); }); $("body").append(form); $("body").append(iframe); } Uploader.BeforeCheck = function (file, opts) { var fileName = ""; var f = null; if ($.browser.msie) { f = document.getElementById($(file).attr("id")); } else { f = document.getElementById($(file).attr("id")).files[0]; } if (!$.browser.msie && f.size > opts.maxsize) { alert(Uploader.ErrorTip.MaxSize); return false; } fileName = $(file).val(); var exts = opts.exts.split("|"); var isExt = false; for (var i = 0; i < exts.length; i++) { if (fileName.indexOf(exts[i]) >= 0) { isExt = true; break; } } if (!isExt) { alert(Uploader.ErrorTip.Ext); return false; } return true; } Uploader.ErrorTip = { MaxSize: "文件超过尺寸", Ext: "文件格式错误" } Uploader.Remove = function (file) { $(file).remove() $("#form_" + $(file).attr("id")).remove(); $("#ifr_" + $(file).attr("id")).remove(); } $.fn.Uploader = function (options) { return new Uploader(this, options); } })
注意:上传图片服务器返回数据json格式是
{code:200,message:"成功",data:{path:"XX/XX/XX.jpg"}}
这是默认可解析的格式,当然自己可以改写
经本人测试支持以下浏览器:
IE6.0+,firefox,chrome,safari其他暂时没有测试