QQ技术群:5678537,70210212,77813547 个人网站:http://www.lovewebgames.com 邮箱:55342775@qq.com

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的文件,代码如下:

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js"  djConfig="dojoBlankHtmlUrl:'blank.html'"></script>

由于是引用的google上的xd文件,所以这里要指定dojoBlankHtmlUrl地址,这个文件是个空白页面,放在本地,因为iframe也要尊从同源策略,不能跨域,如果没有这个文件,冒似也只是会有个警告^_^?

接下来,由于dojo是把dojo.io.iframe这个文件类分离出来的,所以我们还得再引用下它:

<script>
    dojo.require("dojo.io.iframe");
</script>

这里的require和php里的那个require_once效果一样,我在《dojo学习一 之Tab选项卡接触》里有提到它的用法;然后,我们要建一个form表单:

<form id="form1" enctype="multipart/form-data" method="post"> 
        <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>
                    &nbsp;</td>
                <td align="left">
                    <input id="btn_submit" type="submit" value="submit" /></td>
            </tr>
        </table>
    </form>

这里要注意的几点就是,第一行,必须有method="post"和enctype="multipart/form-data",不然为默认使用get请求,最后就是提交这个表单了,请看下面的JS片断:


dojo.io.iframe.send({
            form: "form1",
            handleAs: "json",
            url: "ajax.aspx",
            handle: function(response, args) {
                alert(response.result)
                return response;
            }
        });

它的语法和dojo.xhrXXX的语法是相同的,但它不支持接受xml格式内容,在服务端返回的内容必须放到一个textarea标签里,例如:

Response.Write("<html><body><textarea>{result:\"出错\"}</textarea></body></html>");

 这里就又有个问题了,为什么我要用aspx来作响应,而不用常用的ashx一般处理程序呢?因为我发现啊,在ie里,如果用ashx返回html代码,它会自动解析成页面显示效果形式,但用火狐时,它会把它转义了只显示HTML代码文本形式,而dojo在内部处理接收时,是需要查找真正的dom对象的,所以,用ashx是不兼容火狐的,于是我改用了aspx文件来作为服务器端。但如果是普通的ajax请求就可以使用ashx来处理了,我这里也写了一个试验:

dojo.xhrPost({
            url: "Handler1.ashx",
            handleAs: "text",
            load: function(response, args) {
            console.log(response);
                return response;
            }
        });

 接着是服务端来接收传过来的form值,并保存该文件了,代码和正常的代码一样:

Response.Clear();
            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();

 然后,我在客户端接收到返回的值后,进行处理:

var defer1 = new dojo.Deferred();
        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里返回的也是它,然后我在下面写新的方法来显示刚才上传的图片:

defer1.addCallback(function(response) {
            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试试。

posted @ 2011-11-02 11:29  田想兵  阅读(3848)  评论(6编辑  收藏  举报
联系QQ:55342775,QQ技术群:5678537,70210212,77813547 个人网站:http://www.lovewebgames.com 邮箱:55342775@qq.com