jQuery的ajaxFileUpload插件
关于用ajaxfileupload时,遇到一个要刷新一次页面才能再次上传,用live()方法来绑定 file表单 的change事件就能够解决,直接$("xxx").change()这样只能调用一次,再次调用change的时候不能触发;
IE浏览器下 file表单 选择完成自动提交的问题,在每次处理完成后把 file表单 克隆替换成原来的代码
$("#upload").live("change", function () {
$.ajaxFileUpload(config);
$("#upload").replaceWith($("#upload").clone(true));
})
ajaxFileUpload.js 很多同名的,因为做出来一个很容易。
我用的是这个:https://github.com/carlcarl/AjaxFileUpload
下载地址在这里:http://files.cnblogs.com/files/kissdodog/ajaxfileupload_JS_File.rar
AjaxFileUpload.js并不是一个很出名的插件,只是别人写好的放出来供大家用,原理都是创建隐藏的表单和iframe然后用JS去提交,获得返回值。
当初做了个异步上传的功能,选择它因为它的配置方式比较像jQuery的AJAX,我很喜欢。
评论里面说到的不行。那是因为我们用的不是同一个js。我上github搜AjaxFileUpload出来很多类似js。
ajaxFileUpload是一个异步上传文件的jQuery插件
传一个不知道什么版本的上来,以后不用到处找了。
语法:$.ajaxFileUpload([options])
options参数说明:
1、url 上传处理程序地址。
2,fileElementId 需要上传的文件域的ID,即<input type="file">的ID。
3,secureuri 是否启用安全提交,默认为false。
4,dataType 服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
5,success 提交成功后自动执行的处理函数,参数data就是服务器返回的数据。
6,error 提交失败自动执行的处理函数。
7,data 自定义参数。这个东西比较有用,当有数据是与上传的图片相关的时候,这个东西就要用到了。
8, type 当要提交自定义参数时,这个参数要设置成post
错误提示:
1,SyntaxError: missing ; before statement错误
如果出现这个错误就需要检查url路径是否可以访问
2,SyntaxError: syntax error错误
如果出现这个错误就需要检查处理提交操作的服务器后台处理程序是否存在语法错误
3,SyntaxError: invalid property id错误
如果出现这个错误就需要检查文本域属性ID是否存在
4,SyntaxError: missing } in XML expression错误
如果出现这个错误就需要检查文件name是否一致或不存在
5,其它自定义错误
大家可使用变量$error直接打印的方法检查各参数是否正确,比起上面这些无效的错误提示还是方便很多。
使用方法:
第一步:先引入jQuery与ajaxFileUpload插件。注意先后顺序,这个不用说了,所有的插件都是这样。
<script src="jquery-1.7.1.js" type="text/javascript"></script> <script src="ajaxfileupload.js" type="text/javascript"></script>
第二步:HTML代码:
<body> <p><input type="file" id="file1" name="file" /></p> <input type="button" value="上传" /> <p><img id="img1" alt="上传成功啦" src="" /></p> </body>
第三步:JS代码
<script src="jquery-1.7.1.js" type="text/javascript"></script> <script src="ajaxfileupload.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $(":button").click(function () { ajaxFileUpload(); }) }) function ajaxFileUpload() { $.ajaxFileUpload ( { url: '/upload.aspx', //用于文件上传的服务器端请求地址 secureuri: false, //是否需要安全协议,一般设置为false fileElementId: 'file1', //文件上传域的ID dataType: 'json', //返回值类型 一般设置为json success: function (data, status) //服务器成功响应处理函数 { $("#img1").attr("src", data.imgurl); if (typeof (data.error) != 'undefined') { if (data.error != '') { alert(data.error); } else { alert(data.msg); } } }, error: function (data, status, e)//服务器响应失败处理函数 { alert(e); } } ) return false; } </script>
第四步:后台页面upload.aspx代码:
protected void Page_Load(object sender, EventArgs e) { HttpFileCollection files = Request.Files; string msg = string.Empty; string error = string.Empty; string imgurl; if (files.Count > 0) { files[0].SaveAs(Server.MapPath("/") + System.IO.Path.GetFileName(files[0].FileName)); msg = " 成功! 文件大小为:" + files[0].ContentLength; imgurl = "/" + files[0].FileName; string res = "{ error:'" + error + "', msg:'" + msg + "',imgurl:'" + imgurl + "'}"; Response.Write(res); Response.End(); } }
本实例完整代码下载
来一个MVC版本的实例:
控制器代码
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult Upload() { HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; string imgPath = ""; if (hfc.Count > 0) { imgPath = "/testUpload" + hfc[0].FileName; string PhysicalPath = Server.MapPath(imgPath); hfc[0].SaveAs(PhysicalPath); } return Content(imgPath); } }
前端视图,HTML与JS代码,成功上传后,返回图片真实地址并绑定到<img>的SRC地址
<html> <head> <script src="/jquery-1.7.1.js" type="text/javascript"></script> <script src="/ajaxfileupload.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $(":button").click(function () { if ($("#file1").val().length > 0) { ajaxFileUpload(); } else { alert("请选择图片"); } }) }) function ajaxFileUpload() { $.ajaxFileUpload ( { url: '/Home/Upload', //用于文件上传的服务器端请求地址 secureuri: false, //一般设置为false fileElementId: 'file1', //文件上传空间的id属性 <input type="file" id="file" name="file" /> dataType: 'HTML', //返回值类型 一般设置为json success: function (data, status) //服务器成功响应处理函数 { alert(data); $("#img1").attr("src", data); if (typeof (data.error) != 'undefined') { if (data.error != '') { alert(data.error); } else { alert(data.msg); } } }, error: function (data, status, e)//服务器响应失败处理函数 { alert(e); } } ) return false; } </script> </head> <body> <p><input type="file" id="file1" name="file" /></p> <input type="button" value="上传" /> <p><img id="img1" alt="上传成功啦" src="" /></p> </body> </html>
最后再来一个上传图片且附带参数的实例:控制器代码:
public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult Upload() { NameValueCollection nvc = System.Web.HttpContext.Current.Request.Form; HttpFileCollection hfc = System.Web.HttpContext.Current.Request.Files; string imgPath = ""; if (hfc.Count > 0) { imgPath = "/testUpload" + hfc[0].FileName; string PhysicalPath = Server.MapPath(imgPath); hfc[0].SaveAs(PhysicalPath); } //注意要写好后面的第二第三个参数 return Json(new { Id = nvc.Get("Id"), name = nvc.Get("name"), imgPath1 = imgPath },"text/html", JsonRequestBehavior.AllowGet); } }
Index视图代码:
<html> <head> <script src="/jquery-1.7.1.js" type="text/javascript"></script> <script src="/ajaxfileupload.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $(":button").click(function () { if ($("#file1").val().length > 0) { ajaxFileUpload(); } else { alert("请选择图片"); } }) }) function ajaxFileUpload() { $.ajaxFileUpload ( { url: '/Home/Upload', //用于文件上传的服务器端请求地址 type: 'post', data: { Id: '123', name: 'lunis' }, //此参数非常严谨,写错一个引号都不行 secureuri: false, //一般设置为false fileElementId: 'file1', //文件上传空间的id属性 <input type="file" id="file" name="file" /> dataType: 'json', //返回值类型 一般设置为json success: function (data, status) //服务器成功响应处理函数 { alert(data); $("#img1").attr("src", data.imgPath1); alert("你请求的Id是" + data.Id + " " + "你请求的名字是:" + data.name); if (typeof (data.error) != 'undefined') { if (data.error != '') { alert(data.error); } else { alert(data.msg); } } }, error: function (data, status, e)//服务器响应失败处理函数 { alert(e); } } ) return false; } </script> </head> <body> <p><input type="file" id="file1" name="file" /></p> <input type="button" value="上传" /> <p><img id="img1" alt="上传成功啦" src="" /></p> </body> </html>
此实例在显示出异步上传图片的同时并弹出自定义传输的参数。本实例下载地址
ajaxfileupload去掉pre
data = r.responseText;
var start = data.indexOf(">");
if(start != -1) {
var end = data.indexOf("<", start + 1);
if(end != -1) {
data = data.substring(start + 1, end);
}
}
jquery插件--ajaxfileupload.js
jQuery.extend({
createUploadIframe:
function
(id, uri) {
//id为当前系统时间字符串,uri是外部传入的json对象的一个参数
//create frame
var
frameId =
'jUploadFrame'
+ id;
//给iframe添加一个独一无二的id
var
iframeHtml =
'<iframe id="'
+ frameId +
'" name="'
+ frameId +
'" style="position:absolute; top:-9999px; left:-9999px"'
;
//创建iframe元素
if
(window.ActiveXObject) {
//判断浏览器是否支持ActiveX控件
if
(
typeof
uri ==
'boolean'
) {
iframeHtml +=
' src="'
+
'javascript:false'
+
'"'
;
}
else
if
(
typeof
uri ==
'string'
) {
iframeHtml +=
' src="'
+ uri +
'"'
;
}
}
iframeHtml +=
' />'
;
jQuery(iframeHtml).appendTo(document.body);
//将动态iframe追加到body中
return
jQuery(
'#'
+ frameId).get(0);
//返回iframe对象
},
createUploadForm:
function
(id, fileElementId, data) {
//id为当前系统时间字符串,fileElementId为页面<input type='file' />的id,data的值需要根据传入json的键来决定
//create form
var
formId =
'jUploadForm'
+ id;
//给form添加一个独一无二的id
var
fileId =
'jUploadFile'
+ id;
//给<input type='file' />添加一个独一无二的id
var
form = jQuery(
'<form action="" method="POST" name="'
+ formId +
'" id="'
+ formId +
'" enctype="multipart/form-data" ></form>'
);
//创建form元素
if
(data) {
//通常为false
for
(
var
i
in
data) {
jQuery(
'<input type="hidden" name="'
+ i +
'" value="'
+ data[i] +
'" />'
).appendTo(form);
//根据data的内容,创建隐藏域,这部分我还不知道是什么时候用到。估计是传入json的时候,如果默认传一些参数的话要用到。
}
}
var
oldElement = jQuery(
'#'
+ fileElementId);
//得到页面中的<input type='file' />对象
var
newElement = jQuery(oldElement).clone();
//克隆页面中的<input type='file' />对象
jQuery(oldElement).attr(
'id'
, fileId);
//修改原对象的id
jQuery(oldElement).before(newElement);
//在原对象前插入克隆对象
jQuery(oldElement).appendTo(form);
//把原对象插入到动态form的结尾处
//set attributes
jQuery(form).css(
'position'
,
'absolute'
);
//给动态form添加样式,使其浮动起来,
jQuery(form).css(
'top'
,
'-1200px'
);
jQuery(form).css(
'left'
,
'-1200px'
);
jQuery(form).appendTo(
'body'
);
//把动态form插入到body中
return
form;
},
ajaxFileUpload:
function
(s) {
//这里s是个json对象,传入一些ajax的参数
// TODO introduce global settings, allowing the client to modify them for all requests, not only timeout
s = jQuery.extend({}, jQuery.ajaxSettings, s);
//此时的s对象是由jQuery.ajaxSettings和原s对象扩展后的对象
var
id =
new
Date().getTime();
//取当前系统时间,目的是得到一个独一无二的数字
var
form = jQuery.createUploadForm(id, s.fileElementId, (
typeof
(s.data) ==
'undefined'
?
false
: s.data));
//创建动态form
var
io = jQuery.createUploadIframe(id, s.secureuri);
//创建动态iframe
var
frameId =
'jUploadFrame'
+ id;
//动态iframe的id
var
formId =
'jUploadForm'
+ id;
//动态form的id
// Watch for a new set of requests
if
(s.global && !jQuery.active++) {
//当jQuery开始一个ajax请求时发生
jQuery.event.trigger(
"ajaxStart"
);
//触发ajaxStart方法
}
var
requestDone =
false
;
//请求完成标志
// Create the request object
var
xml = {};
if
(s.global)
jQuery.event.trigger(
"ajaxSend"
, [xml, s]);
//触发ajaxSend方法
// Wait for a response to come back
var
uploadCallback =
function
(isTimeout) {
//回调函数
var
io = document.getElementById(frameId);
//得到iframe对象
try
{
if
(io.contentWindow) {
//动态iframe所在窗口对象是否存在
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML :
null
;
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
}
else
if
(io.contentDocument) {
//动态iframe的文档对象是否存在
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML :
null
;
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
}
catch
(e) {
jQuery.handleError(s, xml,
null
, e);
}
if
(xml || isTimeout ==
"timeout"
) {
//xml变量被赋值或者isTimeout == "timeout"都表示请求发出,并且有响应
requestDone =
true
;
//请求完成
var
status;
try
{
status = isTimeout !=
"timeout"
?
"success"
:
"error"
;
//如果不是“超时”,表示请求成功
// Make sure that the request was successful or notmodified
if
(status !=
"error"
) {
// process the data (runs the xml through httpData regardless of callback)
var
data = jQuery.uploadHttpData(xml, s.dataType);
//根据传送的type类型,返回json对象,此时返回的data就是后台操作后的返回结果
// If a local callback was specified, fire it and pass it the data
if
(s.success)
s.success(data, status);
//执行上传成功的操作
// Fire the global callback
if
(s.global)
jQuery.event.trigger(
"ajaxSuccess"
, [xml, s]);
}
else
jQuery.handleError(s, xml, status);
}
catch
(e) {
status =
"error"
;
jQuery.handleError(s, xml, status, e);
}
// The request was completed
if
(s.global)
jQuery.event.trigger(
"ajaxComplete"
, [xml, s]);
// Handle the global AJAX counter
if
(s.global && ! --jQuery.active)
jQuery.event.trigger(
"ajaxStop"
);
// Process result
if
(s.complete)
s.complete(xml, status);
jQuery(io).unbind();
//移除iframe的事件处理程序
setTimeout(
function
() {
//设置超时时间
try
{
jQuery(io).remove();
//移除动态iframe
jQuery(form).remove();
//移除动态form
}
catch
(e) {
jQuery.handleError(s, xml,
null
, e);
}
}, 100)
xml =
null
}
}
// Timeout checker
if
(s.timeout > 0) {
//超时检测
setTimeout(
function
() {
// Check to see if the request is still happening
if
(!requestDone) uploadCallback(
"timeout"
);
//如果请求仍未完成,就发送超时信号
}, s.timeout);
}
try
{
var
form = jQuery(
'#'
+ formId);
jQuery(form).attr(
'action'
, s.url);
//传入的ajax页面导向url
jQuery(form).attr(
'method'
,
'POST'
);
//设置提交表单方式
jQuery(form).attr(
'target'
, frameId);
//返回的目标iframe,就是创建的动态iframe
if
(form.encoding) {
//选择编码方式
jQuery(form).attr(
'encoding'
,
'multipart/form-data'
);
}
else
{
jQuery(form).attr(
'enctype'
,
'multipart/form-data'
);
}
jQuery(form).submit();
//提交form表单
}
catch
(e) {
jQuery.handleError(s, xml,
null
, e);
}
jQuery(
'#'
+ frameId).load(uploadCallback);
//ajax 请求从服务器加载数据,同时传入回调函数
return
{ abort:
function
() { } };
},
uploadHttpData:
function
(r, type) {
var
data = !type;
data = type ==
"xml"
|| data ? r.responseXML : r.responseText;
// If the type is "script", eval it in global context
if
(type ==
"script"
)
jQuery.globalEval(data);
// Get the JavaScript object, if JSON is used.
if
(type ==
"json"
)
eval(
"data = "
+ data);
// evaluate scripts within html
if
(type ==
"html"
)
jQuery(
"<div>"
).html(data).evalScripts();
return
data;
}
})