首先,我在Google Chrome中工作,如果有帮助的话。这是行为:
我通过jQuery向远程站点发送xhr请求(这是一个chrome扩展,我设置了所有跨站点设置......):
$.ajax({
type: "POST",
contentType : "text/xml",
url: some_url,
data: some_xml,
username: user,
password: pass,
success: function(data,status,xhr){
alert(data);
},
error: function(xhr, status, error){
alert(xhr.status);
}
});
正在设置的网址返回302(这是预期的),Chrome会跟随重定向(也是预期的)。
新网址会返回凭据提示,这些提示不会从原始请求中提取,因此Chrome会显示一个登录对话框。如果我输入原始凭据,我会收到有关发送无效请求的响应(这是一个有效的HTTP请求 - 200 - 远程服务器只是不喜欢其中一个标头)。
在Chrome中查看开发者窗口时,会发送两个请求。第一个是原始URL,其中包含AJAX请求中设置的所有设置。第二个是重定向URL,方法为“GET”,“POST”字段中没有任何内容,也没有凭据。
我不知道我能做些什么。我要么:
获取重定向网址,以便我可以发送第二个请求(xhr.getResponseHeader("Location")
无效),
让新的重定向请求保留原始请求中的设置,或
获取错误来自的最终网址,以便我发送另一个请求。
理想情况下,我不希望用户必须在此对话框中第二次输入他们的凭据,但如果我能获得最终的URL,我将采取我可以获得的信息。
答案 0 :(得分:13)
根据您的问题,我不完全确定您是指代HTTP身份验证还是基于表单的身份验证方案,因此我将解决这两个问题。
获取重定向网址,以便我可以发送第二个请求(xhr.getResponseHeader(“位置”)不起作用),
通常使用XHR的方式(特别是在Chrome中): XHR不是很灵活,并且提供了相对高级的API,浏览器在所有其他请求(地址栏网址,图像源网址,嵌入式脚本网址)中具有相同的行为,即重定向是透明处理的。 JavaScript中不会抛出任何事件,提醒您此重定向或中间302/301状态代码,您只会收到最终的状态代码和数据。因此,无法从响应中检索“Location”标头,因为最终响应不包含“Location”标头。
让新的重定向请求保留原始请求中的设置
XHR不提供此选项,它将是一个不正确的默认行为。为什么在默认情况下会发生这种情况的例子:
Acme corp为其员工提供URL短链接服务。我点击了我从同事处收到的短链接,并通过Acme的短链接服务提示进行HTTP身份验证。此身份验证后会发生重定向。没有理由将站点重定向到需要我的凭据,因此浏览器传递此信息的行为不正确(实际上是安全问题)。同样,不应转发POST数据,因为它只能供预先直接URL使用。
获取错误来自的最终网址,以便我发送另一个请求。
不幸的是,出于安全原因和标准定义,标准XHR对象(包括Chrome用于扩展中的跨站点请求的对象)不提供任何方法来访问有错误的最终URL。您只能访问最终的HTTP状态以及最终URL返回的任何数据。
-
鉴于此,您可以选择一些选项,具体取决于您对情况的控制程度:
1)如果您可以控制重定向服务器,请考虑包含信息。在您的AJAX请求中指示一个AJAX客户端,并让服务器返回数据(即一个json对象),指示应该进行重定向。
或者,如果打算始终传递身份验证数据,请考虑实现一些会话传递机制或包括身份验证信息。在重定向到的URL中,目标URL可以使用此信息。
2)如果您可以控制重定向的目标,请考虑在生成身份验证失败页面时包含目标的URL。 XHR对象可以访问此响应数据,并可以解析它以继续执行新请求。
3)如果您无法控制重定向站点或目标站点,请考虑托管代理服务器来处理请求并专门捕获302。
http://myserver/?url=http://redirectsite.com&user=...&pass=...
4)如果以上都不是选项,那么最不可取但又可行的选择是为运行本机代码的Chrome构建NPAPI扩展。这将使您完全控制请求,并允许您做任何事情。但请注意,这是以更复杂的开发,潜在的安全问题和更少的用户需求为代价的。
答案 1 :(得分:0)
不幸的是,没有办法阻止xhr自动跟踪重定向或设置重定向目标的凭据(无论如何它都会相当不安全,因为这样可以让第一个站点将凭据重定向到任何网站,不仅仅是你想要的网站。)
答案 2 :(得分:0)
您可以尝试此处描述的解决方案类型: How to manage a redirect request after a jQuery Ajax call
这意味着实际上取代了HTTP协议,你也需要控制服务器。所有ajax响应都将在代码200(或至少是3xx,而不是401/403)中使用json对象。在这个json对象中,您可以提供一些特殊的错误代码(为什么不重用
然后扩展jQuery.ajax函数以捕获json响应中的这些特殊代码并生成所需的新请求。实际上,自动jQuery重定向调用是由您完成的,而不是由jQuery完成的。
起初这看起来很难看,但是当处理链接中建议的问题(会话结束,登录页面重定向)时,似乎在客户端和服务器之间的ajax json通信中有完整的协议处理这不是一个坏主意。
答案 3 :(得分:0)
如果您控制服务器,您可能会在重定向地址本身中嵌入丢失的数据。所以xhr做一个POST,然后做一个GET,其中一些POSTed数据被编码回(由服务器)作为GET参数。 没有其他解决方案可供我使用......
答案 4 :(得分:0)
正如Rajiv M.上面所说,你不能使用XHL对象或AJAX请求捕获302重定向。
最好的办法是在PHP / ASP或任何服务器端脚本语言中设置某种代理。 PHP脚本将简单地遵循302重定向,直到它到达最终目的地。然后,它可以将最终的URL发送回您的JavaScript页面。现在,未来的AJAX请求可以直接发送到已知的最终URL。
或者...
您的PHP脚本将仅用作代理。所有请求都将发送到此PHP脚本。
或者...
如果可能的话,只需将最终的URL硬编码到JavaScript应用程序中(尽管我认为在您的情况下不可能)。
抱歉 - 我也讨厌“你不能这样做”的答案,但是有一些JavaScript限制还没有完全消除。
答案 5 :(得分:-3)
你不能使用windows.location =“newURL”吗?曾经为我工作重定向