zoukankan      html  css  js  c++  java
  • Ajax与CustomErrors的尴尬

    在ASP.NET程序中,为了给用户显示友好的错误信息,通常在web.config中进行如下的设置:

    <customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm">
    </customErrors>

    但如果是一个ajax请求在服务端发生了错误,将遭遇一个尴尬。我们就遭遇过这样的尴尬,见下图:

    上图中显示“抱歉!系统发生了错误!”的地方是ajax加载的内容,ajax部分的js代码如下:

    复制代码
    $.ajax({            
        success: function (data) {
            if (data) {
                resultElement.html(data);
            }
        }
    });
    复制代码

    从上面的代码可以知道,虽然ajax请求出错,但依然在success回调函数中处理了,导致将定制错误信息作为正常返回内容显示出来,从而造成前图中的尴尬。

    刚面对这个问题时,我们想到的解决方法是根据statusCode进行判断,如果是500,就知道是发生了错误,然后进行特定的错误处理。我们写了这样的测试代码:

    复制代码
    $.ajax({
        statusCode: {
            500: function () {
                console.log('error!');
            }
        },
        success: function (data) {
            if (data) {
                resultElement.html(' ' + data);
            }
        }
    });
    复制代码

    结果发现,并没有执行对应于500 statusCode的回调函数。

    在浏览器中查看了一下,原来服务器端返回的是302状态码。也就是说,在默认情况下,ASP.NET用重定向的方式向浏览器返回定制错误信息。在web.config>CustomErrors中,有个专门的属性redirectMode,其默认值就是ResponseRedirect。redirectMode还有个值是ResponseRewrite,能不能解决我们的问题呢?我们改一下web.config试一试,修改如下:

    <customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm" redirectMode="ResponseRewrite">
    </customErrors>

    结果发现,的确是返回500状态码了,但定制错误错误没了,返回的是Runtime Error。

    当设置redirectMode="ResponseRewrite",发生错误时,ASP.NET实际会执行Server.Transfer()返回定制错误信息页面,而Server.Transfer()与ASP.NET MVC路由存在兼容问题,详见CustomErrors does not work when setting redirectMode=“ResponseRewrite”

    服务端暂时找不到解决方法,从浏览器端下手试试。

    我们想到一个解决思路,就是根据302 statusCode进行处理,根据我们的实际场景(redirectMode是默认值ResponseRedirect),如果服务端返回的是302,肯定是发生了错误。于是,我们改为如下的ajax代码:

    复制代码
    $.ajax({
        statusCode: {
            302: function () {
                console.log('error!');
            }
        },
        success: function (data) {
            if (data) {
                resultElement.html(' ' + data);
            }
        }
    });
    复制代码

    结果发现,并没有执行302的回调函数,也就是说ajax请求根本拿不到302状态码(http status code),实际得到的还是200状态码。

    既然浏览器端也找不到解决方法,只有“回头是岸”,回到服务器端。

    既然CustomErrors解决不了问题,那我们就把它给废了:

    <customErrors mode="Off">
    </customErrors>

    然后自己处理定制错误信息,在Global.asax.cs中添加如下的代码:

    复制代码
    protected void Application_Error(Object sender, EventArgs e)
    {
        Exception lastError = Server.GetLastError();
        if (lastError != null)
        {
            Response.StatusCode = 500;
            Response.WriteFile("~/error/error.htm");
            Server.ClearError();
        }                        
    }
    复制代码

    问题就这样解决了!

    另外,不用默认的“重定向显示定制错误信息”方式还有一个很大的好处,在发生错误时,浏览器地址栏不会跳转,这样用户反馈错误时,可以直接反馈发生问题时实际访问的完整网址。截个图纪念一下CustomErrors曾经带来的烦恼。

    转载自:http://www.cnblogs.com/dudu/archive/2012/11/20/ajax_custom_error.html

  • 相关阅读:
    验车流程
    WLK毁灭术士天赋图及输出手法
    一个类型集合操作SYS_REFCURSOR的例子
    关于法师真正的输出手法个人观点
    FS技能快界键的设置
    MODEL函数的简单用法。
    kevin的黎明十分
    Android9.0动态运行时权限源码分析及封装改造<四>打造自己的权限申请框架下
    电子书资源
    批量消除图片的杂色背景
  • 原文地址:https://www.cnblogs.com/ideacore/p/6289534.html
Copyright © 2011-2022 走看看