• 解析:使用easyui的form提交表单,在IE下出现类似附件下载时提示是否保存的现象


    之前开发时遇到的一个问题,使用easyui的form提交表单,在Chrome下时没问题的,但是在IE下出现类似附件下载时提示是否保存的现象。

    这里记录一下如何解决的。其实这个现象不光是easyui的form,还有其他一些form插件也是一样的,使用不当就会遇到这个问题。

    前台:

    <!DOCTYPE html>
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="keywords" content="">
        <meta name="description" content="">
        <title></title>
        <link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/default/easyui.css">
        <link rel="stylesheet" type="text/css" href="http://www.jeasyui.com/easyui/themes/icon.css">
        <script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
        <script type="text/javascript" src="http://www.jeasyui.com/easyui/jquery.easyui.min.js"></script>
    </head>
    <body>
        <div>
            <form id="formTest" method="post" action="~/Test/Save">
                name: <input type="text" /><br />
                <a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">submit</a>
            </form>
        </div>
        <script type="text/javascript">
            function submitForm() {
                $('#formTest').form('submit', {
                    success: function(data){
                        var data = $.parseJSON(data);
                        if (data.result){
                            alert(data.msg)
                        }
                    }
                });
            }
        </script>
    </body>
    </html>
    

    后台:

            public ActionResult Save() 
            {
                return Json(new { 
                    result = true,
                    msg = "Save successful."
                });
            }
    

    结果:

    Chrome是这样↓

    IE是这样↓,不科学啊?

    怎么解决?改后台的Action的返回的content-type改为text/html:

            public ActionResult Save() 
            {
                return Json(new { 
                    result = true,
                    msg = "Save successful."
                }, "text/html");
            }
    

    为什么?因为JsonReslut默认返回给浏览器的content-type类型是:application/json,(←等于没说)。

    奇怪了,我们平时通过jQuery的ajax方法来提交数据、请求数据不都挺正常的吗,没出现过这个情况啊,浏览器兼容性jQuery已经帮我们处理好了啊,这个easyui的form方法也是无刷新提交表单啊,应该也是ajax吧。问题就在这里,这个easyui的form提交表单并不是真的ajax。我们来看看easyui-form的源码(正好1.4.2版本的jquery.form.js有源码):

    ...省略...
             function ajaxSubmit(target, options){
            var opts = $.data(target, 'form').options;
            $.extend(opts, options||{});
            
            var param = $.extend({}, opts.queryParams);
            if (opts.onSubmit.call(target, param) == false){return;}
            $(target).find('.textbox-text:focus').blur();
            //构造了一个iframe
            var frameId = 'easyui_frame_' + (new Date().getTime());
            var frame = $('<iframe id='+frameId+' name='+frameId+'></iframe>').appendTo('body')
            frame.attr('src', window.ActiveXObject ? 'javascript:false' : 'about:blank');
            frame.css({
                position:'absolute',
                top:-1000,//让我们看不到它
                left:-1000
            });
            frame.bind('load', cb);
            
            submit(param);
            
            function submit(param){
                var form = $(target);
                if (opts.url){
                    form.attr('action', opts.url);
                }
                var t = form.attr('target'), a = form.attr('action');
                form.attr('target', frameId);//把我们要提交的form的target指向构造出来的那个iframe
                var paramFields = $();
                try {
                    for(var n in param){
                        var field = $('<input type="hidden" name="' + n + '">').val(param[n]).appendTo(form);
                        paramFields = paramFields.add(field);
                    }
                    checkState();
                    form[0].submit();
                } finally {
                    form.attr('action', a);
                    t ? form.attr('target', t) : form.removeAttr('target');
                    paramFields.remove();
                }
             ...省略...

    看我标为红色的,其他的我现在不关心,就先省略了。

    我们看到easyui的作者写了一个ajaxSubmit方法(不仔细看内容还真以为是一个ajax方法呢)。方法里面动态构造了一个隐藏的iframe,然后把我们要提交的form的target指向了构造出来的这个隐藏的iframe,给这个iframe设置了load事件回调方法用来处理响应。重要的是那句“form[0].submit()”,这是什么,这就是直接在提交表单啊,哪儿有什么ajax,只是保证了页面无刷新。(好吧,我承认我理解的ajax概念比较狭隘)

    IE浏览器对于application/json的非ajax的响应的处理比较特殊,我这里指的是相当于你在IE的地址栏上输入了一个url,而服务器返回的content-type是application/json,我猜是IE默认是不能直接处理application/json的响应,所以就提示下载了。

    而Chrome则默认对application/json是当做文本来处理的,所以可以正常显示。

    还有一点需要弄清楚的是ajax,我们看看这个(来自w3school):

    我们看出ajax的响应实际上就两种,一种当做纯文本处理,另一种当做xml处理。所以jQuery的ajax默认对于application/json或者text/html都会当做文本处理的,ajax是没有一种处理方式是“下载保存”的方式的。

    这样应该比较好理解这个问题了。

    可以比较一下用真的ajax来提交表单,不管后台返回的是application/json或者text/html处理都是一致的:

            function submitForm() {
                $.post($("#formTest").attr("action"), {
                    name: $("#formTest input[type=text]").val()
                }, function (response) {
                    alert(response.msg);
                });
            }
  • 相关阅读:
    Python之禅
    浅析css布局模型1
    原型与继承学习笔记4
    原型与继承学习笔记3
    原型与继承学习笔记1
    javascript-this,call,apply,bind简述3
    javascript-this,call,apply,bind简述2
    javascript-this,call,apply,bind简述1
    javascript数组浅谈3
    javascript数组浅谈2
  • 原文地址:https://www.cnblogs.com/liqipeng/p/4609226.html
Copyright © 2020-2023  润新知