zoukankan      html  css  js  c++  java
  • 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试试。

  • 相关阅读:
    概率论中几个入门公式
    记一道贝叶斯公式的裸题
    BZOJ3585: mex(主席树)
    利用MingW检验程序运行内存
    清北集训Day3T1(转换)
    万能pb_ds头文件—bits/extc++.h
    清北集训Day1T3 LYK loves jumping(期望DP)
    洛谷P1962 斐波那契数列(矩阵快速幂)
    namespace用法
    BZOJ4868: [Shoi2017]期末考试
  • 原文地址:https://www.cnblogs.com/tianxiangbing/p/dojo_iframe.html
Copyright © 2011-2022 走看看