Javascript 如何使用 jQuery 阻止 ajax 请求跟随重定向

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8238727/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 05:16:10  来源:igfitidea点击:

How to prevent ajax requests to follow redirects using jQuery

javascriptjquery

提问by J?rgen

I use the jQuery ajax functions to access a web service, but the server, instead of returning a response with a status code describing a problem, the request is redirected to a page with a 200 header, describing the problem. I can't make any changes to this, so I need to solve it on the client somehow.

我使用 jQuery ajax 函数访问 Web 服务,但服务器没有返回带有描述问题的状态代码的响应,而是将请求重定向到带有 200 标头的页面,描述了问题。我无法对此进行任何更改,因此我需要以某种方式在客户端上解决它。

Example: A request goes to some URL which is not found, so I receive a 302 Redirect to another location. A new request is sent, and I receive a 200 OK, thus preventing the error callback to fire.

示例:请求转到某个未找到的 URL,因此我收到 302 重定向到另一个位置。发送了一个新请求,我收到了 200 OK,从而阻止了错误回调触发。

Is there some way I can prevent the ajax request to follow redirects and instead invoke a callback, preferably the error method. Alternatively, is it possible to detect if a redirect has happened in the client?

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

回答by Oleg

I find your question interesting, but the problem in whole seems me more a misunderstanding. At least I'll try to explain my understanding of the problem.

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

The silent (transparent) redirection is the part of XMLHttpRequestspecification (see hereespecially the words "... transparently follow the redirect ..."). The standard mention only that the user agent (the web browser) can prevent or notifyof certain kinds of automatic redirections, but it's not a part of XMLHttpRequest. It's the part of HTTP client configuration (OS configuration) or the web browser configuration. So jQuery.ajaxcan't have any option where you can prevent redirection.

静默(透明)重定向是XMLHttpRequest规范的一部分(请参阅此处特别是“...透明地跟随重定向...”)。该标准仅提到用户代理(Web 浏览器)可以防止或通知某些类型的自动重定向,但它不是XMLHttpRequest. 它是 HTTP 客户端配置(操作系统配置)或 Web 浏览器配置的一部分。所以jQuery.ajax没有任何可以阻止重定向的选项。

You can see that HTTP redirection is the part of HTTP protocol and not a part of XMLHttpRequest. So it's on the another level of abstraction or the network stack. For example the data from the XMLHttpRequestcan be retrieved from the HTTP proxy or from the local browser cache, and it's the part of HTTP protocol. Mostly the serverwhich provide the data and not the client can influence on caching.

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

You can compare the requirement from your question with the requirement to prevent changing of IP address of the web server or the changing of the IP route during the communication. All the things can be interesting in some scenarios, but there are parts of another level of the communication stackand can't be managed by jQuery.ajaxor XMLHttpRequest.

您可以将问题中的要求与防止更改 Web 服务器的 IP 地址或在通信期间更改 IP 路由的要求进行比较。在某些情况下,所有事情都可能很有趣,但是通信堆栈另一个级别的部分不能由jQuery.ajax或管理XMLHttpRequest

The XMLHttpRequeststandard say that the client configuration can have options which prevent redirection. In case of "Microsoft world", which I better know, you can look at WinHttpSetOptionfunction which can be used to set WINHTTP_OPTION_DISABLE_FEATUREoption with the WINHTTP_DISABLE_REDIRECTSvalue. Another way are the usage of WINHTTP_OPTION_REDIRECT_POLICYoption with the WINHTTP_OPTION_REDIRECT_POLICY_NEVERvalue. One more feature which one can use in Windows is the WinHttpSetStatusCallbackfunction which can set callback function received some notifications like WINHTTP_CALLBACK_FLAG_REDIRECT.

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.

So it's do possible to implement your requirements in general, but the solution will be probably not independent from the operation system or the web browser and be not on the level of jQuery.ajaxor XMLHttpRequest.

因此,总体上可以实现您的要求,但该解决方案可能不会独立于操作系统或 Web 浏览器,也不会处于jQuery.ajax或的级别XMLHttpRequest

回答by Jake Feasel

I don't believe it is possible. The underlying library (XHR) makes the new request transparently. That being said, what I have done in these situations (usually a session-timeout type of deal that takes me to a login page) is send back a custom response header. I also have setup a global ajax handler that checks for the presence of that header, and responds appropriately when present (for example, redirecting the whole page to the login screen).

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

In case you're interested, here's the jQuery code I have to watch for that custom header:

如果您有兴趣,这里是我必须注意的自定义标头的 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)

回答by Takman

I found a feature to check if your call has been redirected. It's xhr.state(): if it's "rejected" then a redirection happened.

我发现了一个功能来检查您的呼叫是否已被重定向。它是 xhr.state(): 如果它被“拒绝”,则发生了重定向。

Example with success callback:

成功回调示例:

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

Example with error callback:

错误回调示例:

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

回答by Rialgar

I was interested in the same thing and could not find the state()method mentioned by Takmanand did a little digging for myself. For the sake of people turning up here in search of an answer, here are my findings:

我对同样的事情感兴趣,找不到Takman提到state()方法,自己做了一点挖掘。为了人们来到这里寻找答案,以下是我的发现:

As stated multiple times, you cannot prevent redirects, but you can detect them. According to MDNyou can use the responseURLof the XMLHttpRequestObject, which will contain the final URL the response came from, after all redirects. Only caveat is that it is not supported by Internet Explorer (Edge has it). Since the xhr/jqXHRpassed into the success/donefunction of jquery is an extension of the actual XMLHttpRequest, it should be available there, too.

如前所述,您无法阻止重定向,但可以检测到它们。据MDN可以使用responseURLXMLHttpRequestObject所有重定向后,其中将包含响应来自的最终网址。唯一需要注意的是它不受 Internet Explorer 支持(Edge 支持)。自从xhr/jqXHR传入success/ donejQuery的功能是实际的延伸XMLHttpRequest,它应该可以在那里。

回答by Chris van Hasselt

I can't possibly add to the insightful wisdom of the previous coders who've responded, but I will add a specific case that others may find useful to know about.

我不可能补充以前做出回应的编码人员的有见地的智慧,但我会添加一个其他人可能会觉得有用的特定案例。

I came across this 302 silent redirect in the context of SharePoint. I have some simple Javascript client code that pings a SharePoint sub-site, and if it receives a 200 HTTP response, it relocates to that site, via window.location. If it receives anything else, it gives the user a notice that the site doesn't exist.

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

However, in the case where the site exists but the user does not have permission, SharePoint silently redirects to an AccessDenied.aspx page. SharePoint has already done the HTTP 401 authentication handshake at the server/farm level - the user has access to SharePoint. But the access to the sub-site is handled I suppose using database flags of some sort. The silent redirect bypasses my "else" clause, so I can't throw up my own error. In my case, this is not a show-stopper - it is consistent predictable behavior. But it was a little surprising, and I learned something about HTTP requests in the process!

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

回答by netadictos

I suppose you receive a 200 response because the second time there is no redirection, because the 404 page does not expire, it is saved in the cache. That is to say that the second time the browser gives you the page in the cache. There is a property "cache" in the ajax jquery. http://api.jquery.com/jQuery.ajax/

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

You should write it to "false"

你应该把它写成“false”

回答by cweiske

While it is not possible to disable location redirect following in XmlHttpRequests, it is when using fetch():

虽然无法在XmlHttpRequests 中禁用位置重定向,但它是在使用fetch() 时

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

回答by ipr101

I'm not sure if this will apply in your case, but you can write code to respond to specific status codes in AJAX function -

我不确定这是否适用于您的情况,但您可以编写代码来响应 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.
        }
    }
});

回答by Gfox

In the request headers in the case of ajax request you will have the following

在 ajax 请求的请求标头中,您将拥有以下内容

X-Requested-With    XMLHttpRequest

By this criteria on the server side you can filter requests.

通过服务器端的这个标准,您可以过滤请求。