本问题已经有最佳答案,请猛点这里访问。

我有一个用ASP.NET MVC编写的后端服务器,使用窗体身份验证。当用户未通过身份验证时,服务器将自动发送302重定向到登录操作并返回登录页。

在客户端,我有一个项目列表。只有经过身份验证的用户才能访问此列表。在页面上,我有一个按钮可以使用ajax(jquery的$ajax函数)刷新列表。

现在,我的问题是当身份验证票证超时并且用户单击刷新按钮时:

我的函数发送一个Ajax请求以获取刷新的列表

服务器检测到身份验证票证无效,并发出302重定向。

浏览器自动处理302响应,并强制我的Ajax函数向登录操作发送另一个Ajax请求,最终结果是一个状态为200的HTML。我的脚本很困惑,因为列表也是一个状态为200的HTML。

我想要的是当身份验证票证超时并且用户单击刷新按钮时,我应该能够检测到它并显示一条请求用户登录的消息。

我尝试通过在登录操作中添加自定义头(is_login)并在Ajax响应中检查来解决这个问题。但这不是一个好的解决办法。

所以我的问题是:

解决这个问题的最佳方法是什么?

为什么浏览器不让我们的脚本处理302响应?并自动强制我们的Ajax创建另一个请求。这是浏览器或jquery库的问题吗?有什么原因吗?(安全,…)

谢谢你的回复。

当调用是XHR时,您不应该重定向它,而应该使用401 Unauthorized进行响应,并在回调中处理这个问题。我不知道ASP.NET,但我做了一些与Spring Security类似的事情。

概念如下:

获取已验证状态

检查EDOCX1[1]的收割台

当发现且未经认证时,用401 Unauthorized回复。

当未找到且未通过身份验证时重定向。

底线是,在某些情况下,XHR调用的处理方式与其他HTTP请求的处理方式不同。只有当相同的资源位于另一个位置时,才应该重定向XHR。回答你的问题

您不能用XHR回调处理重定向,因为浏览器会自动处理重定向。您将只返回重定向位置的内容。

谢谢你的回复。您的意思是我们对普通请求使用302,而对Ajax请求只使用401(或任何未使用的状态代码)?

我最大的问题是:为什么我们不能在Ajax中处理302?这背后有什么原因吗?

我知道请求是自动处理的,正如我在问题中所说的那样。但是为什么呢?

因为这就是重定向的本质。有关详细信息,请参阅4.6.7基础结构中w3.org/tr/xmlhttprequest/-send()-方法中的send()方法。

这是来自W3C的,仍然想知道为什么他们不让我们自己处理3xx响应代码。

为什么?只有一种方法可以正确响应重定向。这就是重定向请求。做任何其他事情(比如抓住它并展示一个表单)都没有意义。这就是为什么你需要用一个401来回应。这样您就知道需要授权。302 Found没有提到身份验证。

但至少我们应该能够处理这个问题,以防我们想要重定向页面:window.location.href。

不,你真的不应该。HXR应该要么得到资源要么被告知原因。你可以按照为什么不参与你的代码来行动。如果有人告诉它资源在其他地方,它就不会提供太多上下文。您需要将XHR请求的概念和访问页面的用户分开。