防止 XMLHttpRequest 重定向

问题描述 投票:0回答:7

是否可以在发送 XMLHttpRequest-s 时阻止浏览器遵循重定向(即获取重定向状态代码并自行处理)?

javascript ajax xmlhttprequest
7个回答
111
投票

不符合 XMLHttpRequest 对象的 W3C 标准(已添加强调):

如果响应是 HTTP 重定向:

如果 Location 标头传达的 URL 的来源是同源 与 XMLHttpRequest 来源和 重定向不违反无限 循环预防措施,透明 观察时遵循重定向 同源请求事件规则。

他们正在考虑将其用于未来的版本:

本规格不包括 正在开发以下功能 考虑用于未来版本 此规格:

  • 禁用以下重定向的属性;

最新规范不再提及这一点。


39
投票

新的 Fetch API 支持不同的重定向处理模式:

follow
error
manual
,但我找不到在取消重定向时查看新 URL 或状态代码的方法。您只需停止重定向本身,然后它看起来像一个错误(空响应)。如果这就是您所需要的,那么您就可以开始了。 您还应该注意,通过此 API 发出的请求不可取消。 它们现在

对于XMLHttpRequest,您可以

HEAD
服务器并检查URL是否已更改:

var http = new XMLHttpRequest();
http.open('HEAD', '/the/url');
http.onreadystatechange = function() {
    if (this.readyState === this.DONE) {
        console.log(this.responseURL);
    }
};
http.send();

您不会获得状态代码,但会找到新的 URL,而无需从中下载整个页面。


12
投票

不,XMLHttpRequest 公开的 API 中没有任何地方允许您覆盖其自动遵循 301 或 302 的默认行为。

如果客户端在 Windows 上运行 IE,那么您可以使用 WinHTTP 来设置一个选项来防止该行为,但这是一个非常有限的解决方案。


11
投票

您可以使用

responseURL
属性来获取重定向目的地或检查响应是否最终从您接受的位置获取。
这当然意味着无论如何都会获取结果,但至少您可以获得有关重定向目的地的必要信息,例如检测您想要丢弃响应的条件。


4
投票

我扩展了用户的答案以包含

abort()
电话。当您想要的只是重定向网址时,这似乎可以防止服务器发送太多数据。

var url = 'the url'
var http = new XMLHttpRequest();
http.open('GET', url);
http.onreadystatechange = function() {
    if (this.readyState === this.DONE) {
        console.log(this.responseURL)
        this.abort() // This seems to stop the response
    }
}
http.send()

在现实生活中,我将上面的代码包装在一个承诺中,但这使得代码难以阅读。

另外,我不明白为什么获取重定向网址需要这么困难,但这是另一个时间和地点的问题。


0
投票

如果服务器使用状态代码

307
(临时重定向)发送重定向,则这可以工作(至少在 Chrome 中)。

let xhr = new XMLHttpRequest();
xhr.open("GET", "http://endpoint-that-can-return-redirect", true);
xhr.onreadystatechange = function() {
    if (this.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
        // server responded with headers first
        // 'this.response' is still 'null' here,
        // but 'this.status' is '200', not '307' as could be expected
        let redirect_location = this.responseURL;
        // cancel the request
        this.abort();
        doSomethingWithRedirectLocation(redirect_location);
    }
};
xhr.onload = function(event) {
    if (this.status == 200) {
        // server sends actual data, not a redirect
        let data = this.response; // or 'this.reponseText'
    }
};
xhr.send();


-1
投票

无法在客户端处理重定向或 302 状态,如其他评论中所述。但是您可以阻止重定向。为此,您可以使用“XMLHttpRequest”设置请求标头“X-Requested-With” xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 这应该在打开之后、发送之前完成。下面的例子

let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
   if (this.readyState == 4 && this.status == 200) {
         reqObj.success(JSON.parse(this.responseText))
   } else if (this.status != 200) {
         reqObj.error(this.statusText)
   }
};
xhttp.open(reqObj.type, reqObj.url, reqObj.async);
xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhttp.send();
© www.soinside.com 2019 - 2024. All rights reserved.