您的示例 PAC 文件配置为用于故障转移,而不是用于负载平衡。
换句话说,您的 IE 总是会先尝试通过“proxy1.corp”连接,然后,如果失败,它会尝试通过“proxy2.corp”连接。
请注意,IE 使用“自动代理结果缓存”,您可以在此处阅读:
理论上,每次 Web 浏览器将要获取对象时都会调用 FindProxyForURL() 函数。然而,实际上,Microsoft 的 Internet Explorer 具有 Microsoft 所说的“自动代理结果缓存”。每当成功联系代理 HTTP 服务器(使用调用 FindProxyForURL() 函数的结果或以其他方式定位)以获取对象时,APR 缓存都会更新以包含该对。如果在即将调用 FindProxyForURL() 函数时,Internet Explorer 发现主机已经列在 APR 缓存中,它会使用 APR 缓存条目中列出的代理 HTTP 服务器,而不是为同一主机再次调用 FindProxyForURL() 函数。(APR 缓存的目的是尝试减少 JavaScript 函数必须运行的次数,从而减少获取对象的开销。)因为 Internet Explorer 的 APR 缓存是按主机名索引的,这意味着 PAC 脚本不可能根据除了主机名之外的 URL 的任何部分可靠地产生多个不同的结果。例如,不可能在单个主机上根据 URL 的路径部分提供不同的代理配置。因为 Internet Explorer 的 APR 缓存缓存代理 HTTP 服务器而不是 FindProxyForURL() 函数的完整结果,这意味着即使 FindProxyForURL() 函数出现问题,也不会从一个代理 HTTP 服务器回退到另一个返回了几个代理 HTTP 服务器的列表。这意味着 PAC 脚本不可能根据除了主机名之外的 URL 的任何部分可靠地产生多个不同的结果。例如,不可能在单个主机上根据 URL 的路径部分提供不同的代理配置。因为 Internet Explorer 的 APR 缓存缓存代理 HTTP 服务器而不是 FindProxyForURL() 函数的完整结果,这意味着即使 FindProxyForURL() 函数出现问题,也不会从一个代理 HTTP 服务器回退到另一个返回了几个代理 HTTP 服务器的列表。这意味着 PAC 脚本不可能根据除了主机名之外的 URL 的任何部分可靠地产生多个不同的结果。例如,不可能在单个主机上根据 URL 的路径部分提供不同的代理配置。因为 Internet Explorer 的 APR 缓存缓存代理 HTTP 服务器而不是 FindProxyForURL() 函数的完整结果,这意味着即使 FindProxyForURL() 函数出现问题,也不会从一个代理 HTTP 服务器回退到另一个返回了几个代理 HTTP 服务器的列表。根据单个主机上 URL 的路径部分提供不同的代理配置。因为 Internet Explorer 的 APR 缓存缓存代理 HTTP 服务器而不是 FindProxyForURL() 函数的完整结果,这意味着即使 FindProxyForURL() 函数出现问题,也不会从一个代理 HTTP 服务器回退到另一个返回了几个代理 HTTP 服务器的列表。根据单个主机上 URL 的路径部分提供不同的代理配置。因为 Internet Explorer 的 APR 缓存缓存代理 HTTP 服务器而不是 FindProxyForURL() 函数的完整结果,这意味着即使 FindProxyForURL() 函数出现问题,也不会从一个代理 HTTP 服务器回退到另一个返回了几个代理 HTTP 服务器的列表。
Microsoft 的知识库文章#271361
总结了这些问题并描述了如何关闭 Internet Explorer 的 APR 缓存。Microsoft 的 Internet Explorer 还将“坏”代理 HTTP 服务器的信息缓存 30 分钟。这与 PAC 脚本没有直接关系,只是当人们在设置代理 HTTP 服务器和创建 PAC 脚本时经常会引起混淆,以及代理 HTTP 服务器出现问题,导致它被缓存为“ bad" 30 分钟,被误诊为 PAC 脚本的问题。
如果您想使用 PAC 文件进行负载平衡,请查看此页面以获取一些示例。
但是,即使您在两个代理“proxy1”和“proxy2”之间进行了负载平衡,使用的代理也可能会在每次请求时发生变化;此外,如果您在任何时候都有多个 IE 实例处于活动状态,您可能会遇到一些实例使用“proxy1”而其他实例使用“proxy2”的情况。
因此,要回答您的问题,一种解决方案可能是检查 HTTP 标头响应中的“via”字段。例如,考虑以下 HTML 页面:
<!DOCTYPE html>
<html>
<head>
<title>Javascript Proxy Detection</title>
<script language="javascript">
function doRequest(url) {
if (typeof XMLHttpRequest != 'undefined') {
try {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", url, true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
document.myForm.txt.value = xmlhttp.getAllResponseHeaders();
}
}
xmlhttp.send(null);
} catch (e) {
alert(e.message);
}
} else {
alert('no XMLHttpRequest');
}
}
</script>
</head>
<body>
<form name="myForm">
<textarea cols="50" rows="10" name="txt"></textarea><br />
<input type="button" value="Test Proxy" onclick="doRequest(location.href)">
</form>
</body>
</html>
通过直接连接(没有代理)请求这个页面,然后点击“测试代理”按钮,你会得到这样的输出:
Content-Encoding: gzip
Content-Length: 470
Server: Apache/2.2.17 (Ubuntu)
Vary: Accept-Encoding
Content-Type: text/html
Accept-Ranges: bytes
通过代理(在我的例子中是 Squid)请求相同的页面,您还将获得“通过”字段:
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 470
Content-Type: text/html
X-Cache: MISS from ****
X-Cache-Lookup: HIT from ****:3128
Via: 1.1 ****:3128 (squid/2.7.STABLE9)
因此,通过检查标题中是否存在“via”字段,您应该能够确定:
- 如果您使用代理
- 使用的代理
更多参考资料: