我使用 jQuery ajax 函数来访问 Web 服务,但服务器没有返回带有描述问题的状态代码的响应,而是将请求重定向到带有 200 标头的页面,描述了问题。我无法对此进行任何更改,因此我需要以某种方式在客户端上解决它。
示例:请求转到某个未找到的 URL,因此我收到 302 重定向到另一个位置。发送了一个新请求,我收到了 200 OK,从而阻止了错误回调触发。
有什么方法可以阻止 ajax 请求跟随重定向,而是调用回调,最好是错误方法。或者,是否可以检测客户端中是否发生了重定向?
我使用 jQuery ajax 函数来访问 Web 服务,但服务器没有返回带有描述问题的状态代码的响应,而是将请求重定向到带有 200 标头的页面,描述了问题。我无法对此进行任何更改,因此我需要以某种方式在客户端上解决它。
示例:请求转到某个未找到的 URL,因此我收到 302 重定向到另一个位置。发送了一个新请求,我收到了 200 OK,从而阻止了错误回调触发。
有什么方法可以阻止 ajax 请求跟随重定向,而是调用回调,最好是错误方法。或者,是否可以检测客户端中是否发生了重定向?
我觉得你的问题很有趣,但整个问题在我看来更像是一个误解。至少我会试着解释我对这个问题的理解。
无声(透明)重定向是XMLHttpRequest
规范的一部分(请参阅此处特别是“...透明地跟随重定向...”)。该标准仅提到用户代理(Web 浏览器)可以防止或通知某些类型的自动重定向,但它不是XMLHttpRequest
. 它是 HTTP 客户端配置(操作系统配置)或 Web 浏览器配置的一部分。所以jQuery.ajax
没有任何可以阻止重定向的选项。
您可以看到 HTTP 重定向是 HTTP 协议的一部分,而不是XMLHttpRequest
. 所以它位于另一个抽象级别或网络堆栈上。例如,XMLHttpRequest
可以从 HTTP 代理或本地浏览器缓存中检索来自 的数据,它是 HTTP 协议的一部分。大多数情况下,提供数据的服务器而不是客户端会影响缓存。
您可以将问题中的要求与防止更改 Web 服务器的 IP 地址或在通信期间更改 IP 路由的要求进行比较。在某些情况下,所有事情都可能很有趣,但是通信堆栈的另一个级别的部分不能由jQuery.ajax
或管理XMLHttpRequest
。
该XMLHttpRequest
标准说,客户端配置能够具有防止重定向选项。对于我更了解的“Microsoft world”,您可以查看WinHttpSetOption函数,该函数可用于设置WINHTTP_OPTION_DISABLE_FEATURE
带有WINHTTP_DISABLE_REDIRECTS
值的选项。另一种方法是使用WINHTTP_OPTION_REDIRECT_POLICY
带有WINHTTP_OPTION_REDIRECT_POLICY_NEVER
值的选项。可以在 Windows 中使用的另一项功能是WinHttpSetStatusCallback函数,它可以设置回调函数接收到一些通知,例如WINHTTP_CALLBACK_FLAG_REDIRECT
.
因此,总体上可以实现您的要求,但该解决方案可能不会独立于操作系统或 Web 浏览器,也不会处于jQuery.ajax
或的级别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)
我发现了一个功能来检查您的呼叫是否已被重定向。它是 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");
}
});
我不可能补充以前做出回应的编码人员的洞察力,但我会添加一个其他人可能会觉得有用的特定案例。
我在 SharePoint 上下文中遇到了这个 302 静默重定向。我有一些简单的 Javascript 客户端代码可以 ping 一个 SharePoint 子站点,如果它收到 200 HTTP 响应,它会通过window.location
. 如果它收到任何其他信息,它会通知用户该站点不存在。
但是,在站点存在但用户没有权限的情况下,SharePoint 会以静默方式重定向到 AccessDenied.aspx 页面。SharePoint 已经在服务器/场级别完成了 HTTP 401 身份验证握手 - 用户可以访问 SharePoint。但是我想使用某种数据库标志来处理对子站点的访问。静默重定向绕过了我的“else”子句,所以我不能抛出我自己的错误。在我的情况下,这不是一个表演障碍 - 它是一致的可预测行为。不过有点意外,在这个过程中学到了一些关于HTTP请求的知识!