解析:使用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);
            });
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM