如何防止 ajax 请求遵循使用 jQuery 的重定向

我使用 jQuery ajax 函数来访问 Web 服务,但是服务器不会返回一个带有描述问题的状态代码的响应,而是将请求重定向到一个带有200个标题的页面,该页面描述问题。我不能做任何修改,所以我需要在客户身上解决这个问题。

例如: 一个请求发送到某个没有找到的 URL,所以我收到一个302重定向到另一个位置。一个新的请求被发送,我收到一个200 OK,从而防止错误回调触发。

有没有什么方法可以阻止 ajax 请求遵循重定向,而是调用回调,最好是错误方法。或者,是否可以检测客户机中是否发生了重定向?

98084 次浏览

在 Ajax 请求的请求头中,您将看到以下内容

X-Requested-With    XMLHttpRequest

根据服务器端的此条件,您可以过滤请求。

我觉得这不可能。底层库(XHR)使新请求透明。也就是说,我在这些情况下(通常是会话超时类型的交易,将我带到登录页面)所做的就是发回一个自定义响应头。我还设置了一个全局 ajax 处理程序,用于检查头是否存在,并在出现时作出适当的响应(例如,将整个页面重定向到登录屏幕)。

如果您感兴趣的话,下面是我必须注意的自定义头部的 jQuery 代码:

/* redirects main window when AJAX request indicates that the session has expired on the backend. */
function checkSession(event, xhr, ajaxOptions)
{
if (xhr.readyState == 4)
{
if(xhr.getResponseHeader("Login-Screen") != null && xhr.getResponseHeader("Login-Screen").length)
{
window.location.href='sessionExpired.html'; //whatever
}
}
}


$(document).ajaxComplete(checkSession)

我不确定这是否适用于您的情况,但您可以编写代码,以响应具体的状态代码在 AJAX 函数-

$.ajax({
url: '/admin/secret/data',
type: 'POST',
contentType: 'application/json; charset=utf-8',
statusCode: {
200: function (data) {
alert('302: Occurred');
// Bind the JSON data to the UI
},
401: function (data) {
alert('401: Occurred');
// Handle the 401 error here.
}
}
});

我假设您收到一个200响应,因为第二次没有重定向,因为404页没有过期,它被保存在缓存中。也就是说,浏览器第二次向您提供缓存中的页面时。 在 ajax jquery 中有一个属性“ cache”。 Http://api.jquery.com/jquery.ajax/

You should write it to "false"

我觉得你的问题很有趣,但是整个问题看起来更像是一个误会。至少我会试着解释我对这个问题的理解。

无声(透明)重定向是 XMLHttpRequest规范的一部分(参见 给你,特别是“ ... 透明地遵循重定向...”)。该标准只提到了用户代理(Web 浏览器) 可以防止或通知的某些类型的自动重定向,但它不是 XMLHttpRequest的一部分。它是 HTTP 客户端配置(OS 配置)或 Web 浏览器配置的一部分。所以 jQuery.ajax不能有任何可以防止重定向的选项。

您可以看到,HTTP 重定向是 HTTP 协议的一部分,而不是 XMLHttpRequest的一部分。所以它在另一个抽象层或网络堆栈上。例如,可以从 HTTP 代理或本地浏览器缓存中检索来自 XMLHttpRequest的数据,它是 HTTP 协议的一部分。大多数 服务器提供数据,而不是客户端可以影响缓存。

你可以将问题中的要求与防止在通讯过程中更改网络服务器的 IP 地址或更改 IP 路由的要求进行比较。在某些场景中,所有的事情都很有趣,但是 通信堆栈的另一层的某些部分不能由 jQuery.ajaxXMLHttpRequest管理。

XMLHttpRequest标准规定,客户机配置可以有防止重定向的选项。在“微软世界”的情况下,我更好地知道,你可以看看 WinHttpSetOption函数,它可以用来设置 WINHTTP_OPTION_DISABLE_FEATURE选项与 WINHTTP_DISABLE_REDIRECTS值。另一种方法是使用带有 WINHTTP_OPTION_REDIRECT_POLICY_NEVER值的 WINHTTP_OPTION_REDIRECT_POLICY选项。另一个可以在 Windows 中使用的功能是 WinHttpSetStatusCallback函数,它可以设置回调函数,接收一些通知,如 WINHTTP_CALLBACK_FLAG_REDIRECT

所以总的来说,实现你的需求是可能的,但是这个解决方案可能不会独立于操作系统或者网络浏览器,也不在 jQuery.ajax或者 XMLHttpRequest的层次上。

我不可能增加以前那些有洞察力的程序员的智慧,但是我会增加一个其他人可能觉得有用的案例。

我在 SharePoint 的上下文中偶然发现了这个302无声重定向。我有一些简单的 Javascript 客户端代码,它可以 ping 一个 SharePoint 子站点,如果它接收到200个 HTTP 响应,它就会通过 window.location重新定位到该站点。如果它接收到任何其他信息,它会向用户发出通知,告知该站点不存在。

但是,在站点存在但用户没有权限的情况下,SharePoint 会悄悄地重定向到 AccessDenied.aspx 页面。SharePoint 已经在服务器/场级别完成了 HTTP 401身份验证握手——用户可以访问 SharePoint。但是对子站点的访问是使用某种数据库标志来处理的。静默重定向绕过了我的“ else”子句,所以我不能抛出自己的错误。在我的例子中,这不是一个精彩的表演-它是一致的可预测的行为。但是这有点令人惊讶,在这个过程中我学到了一些关于 HTTP 请求的知识!

我找到了一个功能,可以检查你的电话是否被重定向了。它是 xhr.state () : 如果它被“拒绝”,那么就发生了重定向。

成功回调的例子:

request.success(function(data, textStatus, xhr)
{
if(xhr.state() == "resolved")
{
//no redirection
}
if(xhr.state() == "rejected")
{
//redirection
}
});

错误回调示例:

request.error(function(xhr, textStatus)
{
if (xhr.state() == "rejected")
{
//redirection
location.href = "loginpage";
} else
{
//some other error happened
alert("error");
}
});

我也对同样的事情感兴趣,但是找不到 state()方法 塔克曼提到的,于是为自己做了一些调查。为了让人们来到这里寻找答案,以下是我的发现:

正如多次声明的那样,您不能防止重定向,但是您可以检测到它们。根据 MDN,您可以使用 XMLHttpRequestObjectresponseURL,它将包含响应来自的最终 URL,在所有重定向之后。唯一需要注意的是,它不受 Internet Explorer 的支持(Edge 拥有它)。由于传递给 jquery 的 success/done函数的 xhr/jqXHR是实际 XMLHttpRequest的扩展,因此它也应该可以在那里使用。

虽然在 XmlHttpRequest中不可能禁用位置重定向,但是在使用 拿回来时:

fetch('url', {redirect: manual});