企业IT管理员IE11升级指南 系列:
【1】—— Internet Explorer 11增强保护模式 (EPM) 介绍
【2】—— Internet Explorer 11 对Adobe Flash的支持
【6】—— Internet Explorer 11面向IT专业人员的常见问题
【11】—— 通过SCCM 2012和WSUS部署Internet Explorer 11
【16】—— 使用Compat Inspector快速定位IE兼容性问题
代理自动配置脚本
Contents
简介... 2
设计技巧... 2
处理大小写... 2
有效利用缩进... 3
处理localhost和回送地址... 3
通过PAC屏蔽网站... 3
合理使用变量... 3
慎用isInNet, isResolveable, dnsResolve方法... 4
IE PAC结果缓存... 4
使用Substrings. 4
区分Text和Numeric. 5
负载均衡proxy. 5
调试... 6
本地PAC测试... 6
通过alert()调试... 6
将PAC方法至于HTML页面中调试... 7
PAC文件下载... 7
参考... 7
简介
代理自动配置(Proxy auto-config,简称PAC) 是一种网页浏览器技术,用于定义浏览器该如何自动选择适当的代理服务器来访问一个网址。
一个PAC文件包含一个JavaScript形 式的函数“FindProxyForURL(url, host)”。这个函数返回一个包含一个或多个访问规则的字符串。用户代理根据这些规则适用一个特定的代理其或者直接访问。 当一个代理服务器无法响应的时候,多个访问规则提供了其他的后备访问方法。 浏览器在访问其他页面以前,首先访问这个PAC文件。PAC文件中的URL可能是手工配置的,也可能是是通过网页的网络代理自发现协议(Web Proxy Autodiscovery Protocol)自动配置的。
要使用PAC,我们应当在一个网页服务器上发布一个PAC文件,并且通过在浏览器的代理链接设置页面输入这个PAC文件的URL或者通过使用WPAD协议告知用户代理去使用这个文件。
一个PAC文件是一个至少定义了一个JavaScript函数的文本文件。这个函数FindProxyForURL(url, host)有2个参数:url是一个对象的URL,host是一个由这个URL所衍生的主机名。按照惯例,这个文件名字一般是proxy.pac. WPAD标准使用wpad.dat.
虽然大多数客户端无论从HTTP请求返回的MIME类型是什么都能正确处理,但为了完整性和最佳的兼容性,我们应该设置网页服务器将这个文件的MIME类型声明为 application/x-ns-proxy-autoconfig 或者 application/x-javascript-config .
没有什么理由偏爱一种MIME类型多一些,如果有的话,假设 application/x-ns-proxy-autoconfig 相对 application/x-javascript-config 被更多的客户端所支持是可以理解的。因为它被定义在最初的Netscape规范里面,后者是最近才开始被使用。
一个非常简单的PAC文件内容
function FindProxyForURL(url, host) { return "PROXY proxy.example.com:8080; DIRECT"; }
设计技巧
处理大小写
有些浏览器对大小写敏感,例如www.microsoft.com与WWW.MICROSOFT.COM被认为是不同的主机。如果想忽略大小写,通常情况下可以将参数转换为小写之后进行使用。
var lhost = host.toLowerCase();
host = lhost;
有效利用缩进
有效利用缩进可以提高pac文件的阅读性和可维护性,对于缩进一条简单的规则是花括号之后缩进一个制表符,匹配的花括号之间对齐。
处理localhost和回送地址
localhost和回送地址(127.0.0.1)应该直接跳过代理,可以参考以下逻辑。
if ((host == "localhost") || (shExpMatch(host, "localhost.*")) || (host == "127.0.0.1")) { return "DIRECT"; }
通过PAC屏蔽网站
通过PAC文件可以很容易的屏蔽网站,做法是直接返回一个回送地址使得请求无法送出,这样还可以节省客户端到代理之间的带宽。唯一需要注意的一点是不要将请求发送给本地正在监听的端口。
if (dnsDomainIs(host, ".badspyware.com") || dnsDomainIs(host, ".worsespyware2.com")) { return "PROXY 127.0.0.1:48890"; }
合理使用变量
在PAC文件中合理定义变量可以优化执行效率,增加代码可读性。例如通过以下方式定义变量myip来缓存本地ip地址,这样就避免每次都调用相同方法来查询本地ip。
myip = myIpAddress();
另外一种常见的用法是将准备返回的proxy定义变量,然后随着程序逻辑对其进行更改。
function FindProxyForURL(url, host) { // Set the default proxy variable that users get if they don’t match // any more specific rule. proxy = "PROXY coreproxy.company.com:8000"; // Los Angeles WAN subnets go to LA proxy if (isInNet(myIpAddress(), "10.100.0.0", "255.252.0.0")) { proxy = "PROXY la-proxy.company.com:8000"; } // New York WAN subnets go to New York proxy if (isInNet(myIpAddress(), "10.200.0.0", "255.252.0.0")) { proxy = "PROXY ny-proxy.company.com:8000"; }
一般采用以上方式处理proxy时,逻辑上会先处理最通用的情况然后再处理特殊的情况,最终返回proxy的当前值给浏览器。
return proxy;
慎用isInNet, isResolveable, dnsResolve方法
很多PAC开发人员经常使用isInNet(host,”a.b.c.d”)是否位于某ip段中,但是该方法的调用会使浏览器为每个主机名发送dns反向查询请求。如果一个网络中有很多客户端都在发送类似请求,将大大增加dns服务器的负载。
IE PAC结果缓存
IE的PAC处理存在一个与其他浏览器较大的不同之处,在于IE浏览器会将PAC的处理结果缓存,即可以认为是对于每个host,PAC文件只执行一次,直到下次重启IE才会重新执行。这样就会导致一些PAC逻辑看起来不能正常工作,例如需要通过url中的非host信息来返回不同的代理。
IE PAC结果缓存可以通过以下注册表禁用
HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\CurrentVersion\Internet Settings
Value: EnableAutoproxyResultCache
Type: REG_DWORD
Data value: 0 = disable caching; 1 (or key not present) = enable automatic proxy caching (this is the default behavior)
使用Substrings
如正常的JavaScript方法一样,可以通过使用Substring来判断url或host中部分字符串是否满足特定条件,从而处理不同逻辑,一种比较常见的用法是判断url使用的是那种协议,然后返回不同的代理。
if (url.substring(0,4) == "http") { return "PROXY http-proxy.company.com:8000"; } //matches HTTP and HTTPS URLs if (url.substring(0,3) == "ftp") { return "PROXY ftp-proxy.company.com:8000"; } //matches FTP:// links if (url.substring(0,3) == "mms") { return "PROXY http-proxy.company.com:8000"; } //matches MMS links
区分Text和Numeric
注意字符串类型和数字类型的区别,例如“92”是字符串,如果需要使其变为数字类型,需要调用parseInt方法。
numvariable = parseInt(textvar);
负载均衡proxy
很多机构内部有多个代理服务器,但并没有通过负载均衡器来对代理服务器进行负载管理。通过PAC文件可以通客户端逻辑进行简单的负载均衡。
// Find the 4th octet var myip=myIpAddress() var ipbits=myip.split(".") var myseg=parseInt(ipbits[3]) // Check to see if the 4th octect is even or odd if (myseg==Math.floor(myseg/2)*2) { // Even proxy = "PROXY p1.company.com:8080; PROXY p2.company.com:8080"; } else { // Odd proxy = "PROXY p2.company.com:8080; PROXY p1.company.com:8080"; }
调试
PAC文件的编写难免需要进行测试和调试,例如你在编写过程中出现了JavaScript语法错误,或者有些方法返回了意想不到的结果。很多浏览器并没有提供对于PAC脚本调试的支持,对于PAC文件调试也需要一些技巧。
本地PAC测试
有些情况下PAC文件看上去完全没有起作用,我们可以通过将PAC文件下载到本地,并通过本地文件的方式来访问该PAC文件进行测试。
注意在IE11中默认禁用了本地PAC文件,进行本地PAC文件测试需要更改以下注册表项,
Key: HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\
Value: EnableLegacyAutoProxyFeatures
Type: REG_DWORD
Data: 1
通过alert()调试
通过添加alert()方法可以有效的帮助调试,例如myIpAddress()取得了一个错误的地址,通过alert方法可以很容易的发现类似问题。
if ((host =="proxyinfo.company.com")) {
alert("Local IP address is: " + myIpAddress());
}
alert也可以帮助定位脚本语法错误,例如在不同的逻辑路径上进行alert,正确情况下会弹四个对话框,但最终仅仅弹出三个,那么我们可以判断在第三个于第四个alert之间可能存在语法错误。
将PAC方法至于HTML页面中调试
将PAC文件的function FindProxyForURL(url, host)方法置于html页面中然后通过浏览器打开,可以很容易的发现脚本中的语法错误。
<html> <head> <script language="JavaScript"> Insert your ENTIRE PAC file here </script> </head> <body> test </body> </html>
PAC文件下载
由于PAC文件通常被放在一个Web服务器上,一个常见的问题就是下载问题,判断是否存在PAC文件下载问题,可以通过浏览器直接输入PAC地址尝试下载来查看是否能够下载成功。
参考
http://en.wikipedia.org/wiki/Proxy_auto-config
http://www.proxypacfiles.com/proxypac/