我使用jQuery ajax函数来访问web服务,但服务器不返回一个状态代码描述问题的响应,而是将请求重定向到一个带有200头的页面,描述了问题。我不能做任何更改,所以我需要在客户端上解决它。
例如: 发送到某个URL的请求未找到,因此我收到302重定向到另一个位置。发送新请求后,我收到200 OK,从而防止错误回调触发。
是否有办法防止ajax请求跟随重定向,而是调用回调,最好是error方法。 或者,是否可以检测客户端是否发生了重定向?
我使用jQuery ajax函数来访问web服务,但服务器不返回一个状态代码描述问题的响应,而是将请求重定向到一个带有200头的页面,描述了问题。我不能做任何更改,所以我需要在客户端上解决它。
例如: 发送到某个URL的请求未找到,因此我收到302重定向到另一个位置。发送新请求后,我收到200 OK,从而防止错误回调触发。
是否有办法防止ajax请求跟随重定向,而是调用回调,最好是error方法。 或者,是否可以检测客户端是否发生了重定向?
我认为你的问题很有趣,但整个问题似乎更多是一个误解。至少我会尝试解释我的理解。
静默(透明)重定向是XMLHttpRequest
规范的一部分(请参见这里,特别是“…透明地跟随重定向…”词语)。标准只提到了用户代理(Web浏览器)可能防止或通知某些自动重定向的种类,但这不是XMLHttpRequest
的一部分。这是HTTP客户端配置(操作系统配置)或Web浏览器配置的一部分。因此,jQuery.ajax
没有任何选项可以阻止重定向。
你可以看到HTTP重定向是HTTP协议的一部分,而不是XMLHttpRequest
的一部分。因此它在另一个抽象级别或网络堆栈上。例如,可以从HTTP代理或本地浏览器缓存中检索XMLHttpRequest
的数据,并且这是HTTP协议的一部分。大多数情况下,提供数据的是服务端而不是客户端,可以影响缓存。
你可以将你的要求与防止Web服务器的IP地址更改或在通信期间更改IP路由的要求进行比较。所有这些都可以在某些情况下很有趣,但它们是另一个通信堆栈级别的部分,无法由jQuery.ajax
或XMLHttpRequest
管理。
XMLHttpRequest
标准规定客户端配置可以有选项来防止重定向。在“微软世界”中,我更熟悉的是可以查看WinHttpSetOption函数,该函数可用于设置WINHTTP_DISABLE_REDIRECTS
值的WINHTTP_OPTION_DISABLE_FEATURE
选项。另一种方法是使用WINHTTP_OPTION_REDIRECT_POLICY
选项和WINHTTP_OPTION_REDIRECT_POLICY_NEVER
值。还有一个在Windows中可以使用的功能是WinHttpSetStatusCallback函数,它可以设置回调函数接收一些通知,例如WINHTTP_CALLBACK_FLAG_REDIRECT
。jQuery.ajax
或XMLHttpRequest
级别上。WinHttpSetOption
API(无法在JavaScript中使用,仅存在于Windows上)是我知道防止重定向的唯一方法。此外,我认为您误解了一件事情:重定向使客户端而不是服务器:服务器只返回指令以进行重定向。 - Oleg我不认为这是可能的。底层库(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():如果它是“rejected”,则表示已经被重定向。
成功回调的示例:
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请求的一些东西!
虽然无法禁用 XmlHttpRequests 中的位置重定向跟随,但在使用 fetch() 时可以实现:
fetch('url', {redirect: manual});
我不确定这是否适用于你的情况,但是你可以编写代码来响应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.
}
}
});
X-Requested-With XMLHttpRequest
通过这个标准,你可以在服务器端过滤请求。