详解代理自动配置 PAC
轉自知乎
最近一直在做跨域中華局域網的工作,了解了很多代理知識和基礎概念,很零散,也很細碎。希望通過一段時間的學習,能夠自由地穿梭在國際互聯網和中華局域網之間。后續會寫一系列文章記錄我了解到的知識點,本文要說的是我們平時接觸比較多的 PAC,全名為 proxy auto-config。
什么是 PAC
PAC,一個自動代理配置腳本,包含了很多使用 JavaScript 編寫的規則,它能夠決定網絡流量走默認通道還是代理服務器通道,控制的流量類型包括:HTTP、HTTPS 和 FTP。
它是一段 JavaScript 腳本:
function FindProxyForURL(url, host) { return "DIRECT"; }上面就是一個最簡潔的 PAC 文件,意思是所有流量都直接進入互聯網,不走代理。
PAC 語法和函數
上面函數中,url 字段就是我們在瀏覽器地址欄輸入的待訪問地址,host 為該地址對應的 hostname,return 語句有三種指令:
DIRECT,表示無代理直接連接
PROXY host:port,表示走host:port 的 proxy 服務
SOCKS host:port,表示走host:port 的 socks 服務
而返回的接口可以是多個代理串聯:
return “PROXY 222.20.74.89:8800; SOCKS 222.20.74.89:8899; DIRECT”;
上面代理的意思是,默認走222.20.74.89:8800 的 proxy 服務;如果代理掛了或者超時,則走 222.20.74.89:8899的 socks 代理;如果 socks 也掛了,則無代理直接連接。從這里可以看出 PAC 的一大優勢:自動容災。
PAC 提供了幾個內置的函數,下面一一介紹下:
dnsDomainIs
類似于 ==,但是對大小寫不敏感,
if (dnsDomainIs(host, "google.com") || dnsDomainIs(host, "www.google.com")) { return "DIRECT"; } shExpMatchShell 正則匹配,* 匹配用的比較多,可以是*.http://example.com,也是可以下面這樣,
if (shExpMatch(host, "vpn.domain.com") || shExpMatch(url, "http://abcdomain.com/folder/*")) { return "DIRECT"; } isInNet判斷是否在網段內容,比如 10.1.0.0 這個網段,10.1.1.0 就在網段中,
if (isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0")) { return "DIRECT"; } myIpAddress返回主機的 IP,
if (isInNet(myIpAddress(), "10.10.1.0", "255.255.255.0")) { return "PROXY 10.10.5.1:8080"; } dnsResolve通過 DNS 查詢主機 ip,
if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0") || isInNet(dnsResolve(host), "172.16.0.0", "255.240.0.0") || isInNet(dnsResolve(host), "192.168.0.0", "255.255.0.0") || isInNet(dnsResolve(host), "127.0.0.0", "255.255.255.0")) { return "DIRECT"; } isPlainHostName判斷是否為諸如http://barret/,http://server-name/ 這樣的主機名,
if (isPlainHostName(host)) { return "DIRECT"; } isResolvable判斷主機是否可訪問,
if (isResolvable(host)) { return "PROXY proxy1.example.com:8080"; } dnsDomainLevels返回是幾級域名,比如dnsDomainLevels(http://barretlee.com) 返回的結果就是 1,
if (dnsDomainLevels(host) > 0) { return "PROXY proxy1.example.com:8080"; } else { return "DIRECT"; } weekdayRange周一到周五,
if (weekdayRange("MON", "FRI")) { return "PROXY proxy1.example.com:8080"; } else { return "DIRECT"; } dateRange一月到五月,
if (dateRange("JAN", "MAR")) { return "PROXY proxy1.example.com:8080"; } else { return "DIRECT"; } timeRange八點到十八點,
if (timeRange(8, 18)) { return "PROXY proxy1.example.com:8080"; } else { return "DIRECT"; } alert據說這個函數可以用來調試,不過我在 Chrome 上測試并未生效,
resolved_host = dnsResolve(host); alert(resolved_host);PAC 文件的安裝和注意事項
在 Windows 系統中,通過「Internet選項 -> 連接 -> 局域網設置 -> 使用自動配置腳本」可以找到配置處,下放的地址欄填寫 PAC 文件的 URI,這個 URI 可以是本地資源路徑(file:///),也可以是網絡資源路徑(http://)。
Chrome 中可以在「chrome://settings/ -> 顯示高級設置 -> 更改代理服務器設置」中找到 PAC 填寫地址。
需要注意的幾點:
PAC 文件被訪問時,返回的文件類型(Content-Type)應該為:application/x-ns-proxy-autoconfig,當然,如果你不寫,一般瀏覽器也能夠自動辨別
FindProxyByUrl(url, host) 中的 host 在上述函數對比時無需轉換成小寫,對大小寫不敏感
沒必要對 dnsResolve(host) 的結果做緩存,DNS 在解析的時候會將結果緩存到系統中
轉載于:https://www.cnblogs.com/linuxde/p/8718437.html
總結
以上是生活随笔為你收集整理的详解代理自动配置 PAC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 201571030310/2015710
- 下一篇: webpack流程图