问题
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.
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());
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;
}
}
}
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).
How can I recognize that a javascript fetch() call was made? Is there something similar to "IsAjaxRequest"?
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);
});
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);
}
回答1:
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' } })
来源:https://stackoverflow.com/questions/55048830/how-recognize-javascript-fetch-inside-handleerrorattribute-onexception