发送 XMLHttpRequest-s 时是否可以防止浏览器跟随重定向(即获取重定向状态代码并自己处理)?
6 回答
不符合XMLHttpRequest 对象的 W3C 标准(已添加重点):
如果响应是 HTTP 重定向:
如果 Location 标头传达的 URL 的来源与 XMLHttpRequest 的来源相同,并且重定向不违反无限循环预防措施,则在遵守同源请求事件规则的同时透明地遵循重定向。
他们正在考虑将其用于未来的版本:
本规范不包括正在考虑用于本规范的未来版本的以下功能:
- 禁用以下重定向的属性;
但最新的规范不再提及这一点。
新的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,而无需从中下载整个页面。
不,您在 XMLHttpRequest 公开的 API 中没有任何地方允许您覆盖其自动遵循 301 或 302 的默认行为。
如果客户端在 Windows 上运行 IE,那么您可以改用 WinHTTP 来设置一个选项来防止该行为,但这是一个非常有限的解决方案。
您可以使用responseURL
属性来获取重定向目标或检查响应最终是否是从您接受的位置获取的。
这当然意味着无论如何都会获取结果,但至少您可以获得有关重定向目标的必要信息,例如检测您想要丢弃响应的条件。
正如其他评论中所回答的那样,无法在客户端处理重定向或 302 状态。但是,您可以防止重定向。为此,您可以使用 "XMLHttpRequest" xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); 设置请求标头 "X-Requested-With" 这应该在打开之后但在发送之前完成。下面的例子
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();
我扩展了用户的回答以包括一个abort()
电话。当您想要的只是重定向 url 时,这似乎可以防止服务器发送太多数据。
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()
在现实生活中,我将上面的代码包装在一个 Promise 中,但它使代码难以阅读。
另外,我不明白为什么获取重定向 url 需要这么困难,但这是另一个时间和地点的问题。