js无刷新无插件异步上传文件,使用dojo.io.iframe发送form数据包
js无刷新无插件上传文件,使用dojo.io.iframe发送form数据包
作者:田想兵
说到无刷新,可能大多数时候,大家都会想到使用ajax,但实际上呢,有很多时候,仅使用ajax是无法达到目的的,如果你想更好的完成工作,可能还会使用一些非常规的方式,比如你可能会使用activeX或flash这类的插件,但这些不是本文的重点,本文重点是如果使用iframe来上传文件,说到iframe,估计有很多人会嗤之以鼻,对于这类人,我建议您还是不要继续观看,以免污了您的眼睛。
本文案例请点击这里:js无刷新无插件上传文件,使用dojo.io.iframe发送form数据包
dojo这个js库,我就不多介绍了,大家可以看我前面的文章,里面有介绍dojo的,《dojo学习一 之Tab选项卡接触》,其实它和YUI、Extjs这类库比较相像,和jquery嘛,也越来越像了。首先,我们要引用dojo的文件,代码如下:
由于是引用的google上的xd文件,所以这里要指定dojoBlankHtmlUrl地址,这个文件是个空白页面,放在本地,因为iframe也要尊从同源策略,不能跨域,如果没有这个文件,冒似也只是会有个警告^_^?
接下来,由于dojo是把dojo.io.iframe这个文件类分离出来的,所以我们还得再引用下它:
dojo.require("dojo.io.iframe");
</script>
这里的require和php里的那个require_once效果一样,我在《dojo学习一 之Tab选项卡接触》里有提到它的用法;然后,我们要建一个form表单:
<table class="style1">
<tr>
<td>
文件名:</td>
<td align="left">
<input id="txt_name" name="txt_name" type="text" /></td>
</tr>
<tr>
<td>
文件地址:</td>
<td align="left">
<input id="f_img" name="f_img" type="file" /></td>
</tr>
<tr>
<td>
</td>
<td align="left">
<input id="btn_submit" type="submit" value="submit" /></td>
</tr>
</table>
</form>
这里要注意的几点就是,第一行,必须有method="post"和enctype="multipart/form-data",不然为默认使用get请求,最后就是提交这个表单了,请看下面的JS片断:
form: "form1",
handleAs: "json",
url: "ajax.aspx",
handle: function(response, args) {
alert(response.result)
return response;
}
});
它的语法和dojo.xhrXXX的语法是相同的,但它不支持接受xml格式内容,在服务端返回的内容必须放到一个textarea标签里,例如:
这里就又有个问题了,为什么我要用aspx来作响应,而不用常用的ashx一般处理程序呢?因为我发现啊,在ie里,如果用ashx返回html代码,它会自动解析成页面显示效果形式,但用火狐时,它会把它转义了只显示HTML代码文本形式,而dojo在内部处理接收时,是需要查找真正的dom对象的,所以,用ashx是不兼容火狐的,于是我改用了aspx文件来作为服务器端。但如果是普通的ajax请求就可以使用ashx来处理了,我这里也写了一个试验:
url: "Handler1.ashx",
handleAs: "text",
load: function(response, args) {
console.log(response);
return response;
}
});
接着是服务端来接收传过来的form值,并保存该文件了,代码和正常的代码一样:
try
{
HttpPostedFile hpf = Request.Files[0];
if ("image/gif,image/bmp,image/png,image/jpg,image/jpeg".Split(',').Contains(hpf.ContentType.ToLower()))
{
string filename = "/upload/" + Request.Form["txt_name"] + ".jpg" ;
string filePath = Server.MapPath(filename);
hpf.SaveAs(filePath);
Response.Write("<html><body><textarea>{result:\"ok\",imgUrl:\"" + filename + "\"}</textarea></body></html>");
}
else
{
Response.Write("<html><body><textarea>{result:\"文件格式:.gif,.bmp,.png,.jpg,.jpeg\"}</textarea></body></html>");
}
}
catch
{
Response.Write("<html><body><textarea>{result:\"出错\"}</textarea></body></html>");
}
Response.End();
然后,我在客户端接收到返回的值后,进行处理:
dojo.io.iframe.send({
form: "form1",
handleAs: "json",
url: "ajax.aspx",
handle: function(response, args) {
if (response.result == "ok") {
defer1.callback(response)
} else {
defer1.errback(new Error(response.result));
alert(response.result)
}
return response;
}
});
这里又有一个新的东西了,叫dojo.Deferred,翻译过来就是“延迟处理”,因为很多时候,你不太可能把所有的代码都写在ajax返回方法,这个时候,就可以用到它了,好像jquery1.5之后才出现这个功能,有兴趣的可以了解下,这里我就不多说了,大家只需要知道它可以把方法引到外面来就行了,dojo的ajax里返回的也是它,然后我在下面写新的方法来显示刚才上传的图片:
var newNode = document.createElement("img");
dojo.attr(newNode, "src", response.imgUrl);
dojo.place(newNode, dojo.query("body")[0], "last");
return response;
})
这样写,它会在处理完提交后,按顺序自动调用这个方法。你只要一直return response;你就可以一直addCallback,有人叫这为"模拟进程"。如果你对此感兴趣可以加Q群:70210212或77813547,我们可以探讨下。
好了,一切到这里就算圆满结束了,可能你会发现状态栏似乎也刷了一下,但其实只是隐藏的一个iframe刷了,并不会影响你当前的页面操作,你真正的页面并没有动,不信你F5试试。