本文介绍了如何识别HandleErrorAttribute OnException中的javascript fetch()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在asp.net mvc应用程序中,我成功处理了从JavaScript到Controller进行jquery $ .ajax调用时发生的异常。当我从javascript进行javascript fetch()调用时,我想以相同的方式处理错误,但是我不知道如何识别进行了fetch()调用。

In an asp.net mvc application, I'm successfully handling exceptions that occur when I make a jquery $.ajax call from javascript to a Controller. I want to handle errors in the same way when I make a javascript fetch() call from javascript, but I cannot figure out how to recognize that a fetch() call was made.

我正在使用从HandleErrorAttribute派生的类来处理所有Controller错误。这是通过将以下行添加到global.asax Application_Start来完成的:

I'm using a class derived from HandleErrorAttribute to handle all Controller errors. This is done by adding the following line to global.asax Application_Start:

GlobalFilters.Filters.Add(new Areas.Insurance.Helpers.MyHandleErrorAttribute());

在MyHandleErrorAttribute中,我重写了OnException方法,以便与常规get或发布错误。如果出现ajax错误,我希望返回一个包含guid的对象并触发javascript中的$ .ajax error:回调。如果有由javascript fetch()调用引起的错误,我希望response.ok返回 false,并传递回包含错误guid的对象。如果错误不是ajax错误或javascript fetch()错误,我想重定向到我们的自定义错误页面。代码如下所示:

In MyHandleErrorAttribute I'm overriding the OnException method so that I can treat Ajax errors differently then regular get or post errors. If there is an ajax error my desire is to return an object that contains a guid and trigger the $.ajax "error:" callback in javascript. If there is an error caused by a javascript fetch() call I want the response.ok to return "false" and pass back an object that contains the error guid. If the error is not an ajax error or javascript fetch() error I want to redirect to our custom error page. The code looks like this:

public override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception == null)
            return;

        //log the error
        Guid guid = MyClass.LogError(filterContext.Exception.GetBaseException());

        if (filterContext.HttpContext.Request.IsAjaxRequest()
            && filterContext.Exception != null)
        {
            //this is an error from a $ajax call.
            //500 is needed so that $ajax "error:" function is hit, instead of "success:"
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            filterContext.Result = new JsonResult()
            {
                Data = new MyErrorObject()
                {
                    Guid = guid
                }
                ,JsonRequestBehavior = JsonRequestBehavior.AllowGet
                //JsonRequestBehavior.AllowGet prevents following sporadic error: System.InvalidOperationException: This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.
            };

            //this stops Application_OnError from firing
            filterContext.ExceptionHandled = true;

            //this stops the web site from using the default IIS 500 error. 
            //in addition must set existingResponse="Auto" ("PassThrough also works) in web.config httpErrors element.
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
        else
        {
            //if condition to avoid error "Server cannot set status after HTTP headers have been sent"
            if (!filterContext.HttpContext.Response.IsRequestBeingRedirected)
            {
                filterContext.Result = new RedirectToRouteResult(
                    new System.Web.Routing.RouteValueDictionary
                    {
                    {"action", "Error500" },
                    {"controller", "Error" },
                    { "Guid", guid}
                    });
                filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                filterContext.ExceptionHandled = true;
            }
        }
    }

我的问题是,使用javascript fetch()进行调用时, IsAjaxRequest返回false,因此未命中第一个 if块。相反,我进入 else块,该块将Http Response设置为 OK,并重定向到我的错误页面,这都不是必需的(当我遇到fetch()错误时,我想返回500响应,当然重定向也没有效果。)

My problem is, when a call is made using javascript fetch(), "IsAjaxRequest" returns false, so the first "if" block is not hit. Instead I am going into the "else" block, which sets the Http Response to "OK" and does a redirect to my error page, both of which are not desired (when I get a fetch() error I want to return a 500 response, and of course the redirect has no effect).

我如何识别进行了javascript fetch()调用?有什么类似于 IsAjaxRequest吗?

How can I recognize that a javascript fetch() call was made? Is there something similar to "IsAjaxRequest"?

这是JavaScript提取的样子:

Here is what the javascript fetch looks like:

let url = '/myDomain/ThrowException';
    fetch(url)
        .then(function (data) {
          if(data.ok){
            //do something with data
           }
          else{
              handleHttpErrorFunction(data);
          }
        })
        .catch(function (error) {
            handleFetchErrorFunction(error);
        });

这是我想用fetch()替换的(成功处理的)jQuery ajax调用呼叫:

And here is the (successfully handled) jquery ajax call that I want to replace with a fetch() call:

 $.ajax({
        url: '/myDomain/ThrowException',
        type: 'GET',
        success: function (data) {
            //do something with data
        },
        error: function (XMLHttpRequest, ajaxOptions, ex) {
            ajaxerrorhandler(XMLHttpRequest);
        }


推荐答案

请参见在。解决方法是在标头中发送X-Requested-With XMLHttpRequest:

See answer to related question at From server, how recognize javascript fetch() call was made (asp.net mvc). The fix is to send X-Requested-With XMLHttpRequest in the headers:

fetch('/MyDomain/MyControllerAction', { headers: { 'X-Requested-With': 'XMLHttpRequest' } })

这篇关于如何识别HandleErrorAttribute OnException中的javascript fetch()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 11:21