Mistaken Response Code Detected on MVC AJAX Call

When making a request using $.ajax(), I typically do it like this:

$.ajax({
    type: "GET",
    url: myUrl
    success: function(data) {
        $("#replace").html(data)
    },
    error: function (data) {
        console.warn(data);
    }
});

Another way is to attach handlers to the promises of the ajax call:

$.ajax({
    type: "GET",
    url: myUrl
})
.done(function(data, status) {
    console.log(data);
})
.fail(function(data, status) {
    console.warn(status);
});

In both scenarios, the error/fail function is triggered when there's an HTTP status error.


In my ASP.NET MVC project, I want to return the proper HTTP Status Code. This is important from a semantic perspective and for accurate handling on the client side.

Attempt #1 - Following advice provided in this answer, I tried returning a HttpStatusCodeResult like this:

protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
    if (filterContext.HttpContext.Request.IsAjaxRequest())
    {
        filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized, accessResult.AccessDeniedMessage);
        filterContext.HttpContext.Response.End();
    }
    else
    {
       base.HandleUnauthorizedRequest(filterContext);
    }
}

Attempt #2 - Alternatively, as suggested in this answer, I attempted returning a JsonResult while setting the Response.StatusCode:

filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
filterContext.Result = new JsonResult()
{
    Data = new { Error = "Unauthorized User" },
    JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.HttpContext.Response.End();

Despite these efforts, the response still indicates 200 OK.

https://i.sstatic.net/jEy2K.png

Questions:

  • Is it correct that an AJAX response should include an Unauthorized status code?
  • Do I need to set this value elsewhere as well?
  • Are there server-level configurations that need adjustment to allow non-200 status codes?

This issue discussed in Always success on ajax post with HttpResponseMessage 401 seems similar but lacks a clear solution at the server side level, resorting instead to accepting the OK error status code and inspecting responses for errors manually.

Answer №1

The issue at hand was similar to the one discussed in Always success on ajax post with HttpResponseMessage 401. The response was successfully returned, but it triggered a redirect to a form login page.

<b>X-Responded-JSON</b>: {"status": 401, "headers": {"location":"http:\/\/localhost:50004\/Login?ReturnUrl=%2FClient"}}

While the original question did not propose a server-side solution and focused more on handling errors on the client side, Brock Allen recommended a server-side fix in his article about Using cookie authentication middleware with Web API and 401 response codes:

Typically, when using cookie authentication middleware and encountering a 401 status code on the server (MVC or WebForms), the response is converted into a 302 redirect to the login page indicated by the LoginPath in the CookieAuthenticationOptions. However, this behavior is not ideal for Ajax calls that expect a 401 response without redirection. To address this, you need to customize the action taken upon receiving a 401 unauthorized response by configuring a CookieAuthenticationProvider:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
   AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
   LoginPath = new PathString("/Account/Login"),
   Provider = new CookieAuthenticationProvider
   {
      OnApplyRedirect = ctx =>
      {
         if (!IsAjaxRequest(ctx.Request))
         {
            ctx.Response.Redirect(ctx.RedirectUri);
         }
     }
   }
});

This snippet specifically handles the OnApplyRedirect event. If the call is not an Ajax request, it redirects; otherwise, it allows the 401 response to be sent back to the caller.

The IsAjaxRequest check used here is borrowed from a helper in the katana project:

private static bool IsAjaxRequest(IOwinRequest request)
{
   IReadableStringCollection query = request.Query;
   if ((query != null) && (query["X-Requested-With"] == "XMLHttpRequest"))
   {
      return true;
   }
   IHeaderDictionary headers = request.Headers;
   return ((headers != null) && (headers["X-Requested-With"] == "XMLHttpRequest"));
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dealing with null values in Ajax responses with coffeescript

I am currently facing an issue with my ajax code written in CoffeeScript. Although the response containing JSON is visible in the browser's panel, all variables remain undefined on success. Can anyone provide assistance with this? Below is the snippe ...

How to Include JavaScript Files in an HTML Document

I was curious about how loading static .js files appears To load the file, use: <script src="{% static 'js/base.js' %}" /> Probably need the .js file because I will try to use this NavBar like in this example where the Login has a red fra ...

Dynamic Data Causes Highcharts Date Formatting to Adapt

I wanted to create a line graph using Highcharts with the Date Format on x-axis set to "%b %e". For example, I expected 06/27/2014 to be displayed as Jun 17. Despite setting the date-format correctly, Highcharts seems to automatically change it when rende ...

Error encountered when using Prisma Client in conjunction with Next Auth.js

I encountered an error while working on Next Authentication with the Google adapter. The specific error message is as follows: ✓ Compiled /api/auth/[...nextauth] in 371ms (70 modules) (node:9269) [DEP0040] DeprecationWarning: The `punycode` module is dep ...

The issue with modal form submission in Laravel 8 is due to a malfunctioning Ajax code

I'm trying to submit a modal form and display a success message without refreshing the page. Here is the code I'm using : The View : <x-app-layout> <div class="container-fluid"> <div class="row"> ...

Utilizing Vue-cli and Three.js to Load STL Files

I'm facing an issue where I can't seem to load an STL file into a three.js scene that is being created via vue-cli. The project setup involves using vue-cli 'vue init webpack ProjectName', 'cd ProjectName', 'npm install ...

D3: Ensuring Map is Scaled Correctly and Oriented Correctly

I am attempting to integrate a map into a website using D3 and topoJSON that resembles the following: https://i.sstatic.net/1brVx.png However, when I create the map with D3/topoJSON, it shows up small and inverted. https://i.sstatic.net/LgQBd.png Even ...

RXJS - distinguishing between values based on multiple keys

I am looking to trigger .subscribe() for my observable when any one of three object keys has been changed. The method works if I manually duplicate it for each key: this.myService.loadData(this.dataContainer.id, true) .distinctUntilChanged((updated ...

Tips for arranging accordion buttons side by side so they all expand into a single element

I'm currently working on a unique accordion design where multiple buttons expand into individual areas below when clicked. The standard accordion layout isn't quite what I'm aiming for. I envision the buttons all in a row, and when clicked, ...

`A brief disruption in loading the visual style of Google Maps`

Using the Ionic Framework, AngularJS, and Google Maps API, I encountered an irritating issue with my mobile app. Every time the map loads, there is a noticeable delay in loading the map style. This delay is particularly problematic as my map style converts ...

Using Vue2: It is recommended to refrain from directly mutating a prop inside a component

When attempting to determine if a person's input should be considered invalid due to being empty, I keep encountering the error message "Avoid mutating a prop directly". <script type="text/x-template" id="srx"> <input type="number" name="p ...

Struggling to properly access an object in EJS template engine

I am encountering an issue with an object I am passing into my EJS template, as I keep receiving an error message stating Cannot read property 'link' of undefined. Below is the object and the corresponding template code. Upon logging the object, ...

Experiencing problems with geolocation feature policy while working with Ionic framework

Currently, I have integrated Google maps into my Ionic project using the code snippet below: this.geolocation.getCurrentPosition().then((position) => { let latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); let ...

Alter the URL and CSS upon clicking an element

Currently, I am faced with a challenge on my website where I have multiple pages that utilize PHP to include content and jQuery to toggle the display of said content by adjusting CSS properties. However, I am encountering difficulty in implementing this ...

Using Node.js to Insert Data into MySQL

I recently started experimenting with node.js and decided to use node-mysql for managing connections. Even though I am following the basic instructions from the github page, I am unable to establish a simple connection successfully. var mysql = require(& ...

The customization of a Wordpress theme is causing an issue: the CSS class cannot be

I have been trying to customize a free version of a popular WordPress theme called EmpowerWP. Despite searching through all the files on the website, I have been unable to find a specific CSS class that I am looking for. As a result, I am considering two ...

Transforming into a serialized division

I am working on creating a custom WISYWIG editor that generates a div with specific inner elements. The goal is to design the div (along with its inner structure), serialize it, store it in a database as a string or JSON format, and later insert it into th ...

SSL and localhost causing CORS Access Denied in IE11 and later versions

Has anyone successfully managed to request local resources via AJAX in IE over SSL without encountering an "access denied" error? In a nutshell: I'm using AJAX to fetch JSON from a local web service that is encrypted when served over HTTPS to avoid ...

Tips for truncating text within a textarea

I need help with trimming text inside a textarea and displaying the result. For example: " 1234 " should become "1234" Unfortunately, my current code is not working as expected. It doesn't trim the text and returns nothing. This is the HTML ...

Transferring a variable from a .jsp file to a .js file

I'm currently working on a .jsp page where the appearance of a different div from a .js file depends on the header that comes from a request. I've added a second header and now want if (info.getLightHeader()!=null) the <div id="lightHeader ...