1. 程式人生 > >自動切換IE代理設定: 簡單使用IE自動配置指令碼

自動切換IE代理設定: 簡單使用IE自動配置指令碼

今天和一個朋友聊到了chrome的自動代理功能,很多人感覺這個功能非常方便,但大家或許不知道這個功能其實是繼承自IE瀏覽器,而且在“遙遠”的Windows 98時代IE就已經具有了這個功能。這個功能在IE中被稱作Proxy Automatic Configuration簡稱PAC,這個功能在1996年由Netscape公司開發,隨著被IE支援後成為一個業內統一標準。

那麼我們在什麼情況下需要用到PAC呢?簡單的說就是我們需要對一部分網站需要用到特定的代理服務,比如我們公司的內部辦公系統就需要用到一個公司的內部代理去訪問,而這個代理又不能連線外網,這時候如果我們在訪問這些網站時再手動設定代理就會非常麻煩。用PAC就會輕鬆得多。

如何配置PAC

PAC的配置方法非常簡單,不需要安裝任何軟體或外掛,只需用記事本建立一個腳步檔案即可,我們可以把這個檔案儲存在硬碟的任何位置,也可以儲存在伺服器上,然後開啟Internet選項 - 進入 連線 選項卡 - 點選區域網選項 - 選中 使用自動配置指令碼 選項 -  在地址裡面填入你的檔案位置,比如files://d:/goagent.pac ,即可完成配置。

image

PAC檔案的內容

那麼PAC檔案中應該寫些什麼呢?其實這個檔案只是一個在配置一個叫做FindProxyForURL(url, host)的JScript函式。比如這個檔案的內容可以是:

function FindProxyForURL(url, host) { return "PROXY DIRECT; PROXY 192.168.0.1:8080; SOCKS 192.168.1.1:1080 "; } 這是一個最簡單的PAC指令碼,意思就是讓對於所有網站都直接進行連線,如果不能連線就嘗試使用http代理192.168.0.1進行連線,如果仍然無法連線就嘗試SOCKS代理192.168.1.1。

通過上面的示例大家不難看出IE在呼叫這個函式的時候會傳入兩個變數來,一個是地址URL全路經,另一個是URL中的主機名部分。而函式在返回的時候可以是三種值,DIRECT代表直接連線,PROXY代表HTTP代理,SOCKS代表SOCKS型別代理。

典型應用

根據URL判斷是否需要代理

function FindProxyForURL(url, host) {
   if (shExpMatch(url,"*.facebook.com/*")) {
     return "PROXY 127.0.0.1:8087";
   }
   return "DIRECT";
}

shExpMatch這個函式可能是寫PAC指令碼中最常用到的了,在本示例中的作用實現對於facebook 域名下的頁面呼叫127.0.0.1:8087這個代理,而其他URL直接訪問。

代理不能解析的主機

function FindProxyForURL(url, host)
{
  if (isResolvable(host))
    return "DIRECT";
  else
    return "PROXY 127.0.0.1:8087";
}

這個isResolvable函式實現的功能就是當某個主機域名不能被正常解析的時候就嘗試代理訪問,比如公司內部如果有獨立的DNS而這臺DNS又只解析內部地址,就可以利用這個函式自由的切換內外網了,當然也可以用來對付某些ISP的域名劫持。

在家庭和公司之間自動切換

function FindProxyForURL(url, host)
{
if (myIpAddress() == "192.168.0.254") {
return “PROXY 127.0.0.1:80″;
}
else {
return “DIRECT”;
}
}

如果你習慣在下班後將筆記本帶回家中的話myIpAddress函式將會十分有用,示例中實現的作用是當本機ip為192.168.0.254的時候就使用127.0.0.1:80這個代理,否則直接連線。

隨機選擇代理

function FindProxyForURL(url,host)
{
return randomProxy();
}

function randomProxy()
{
switch( Math.floor( Math.random() * 5 ) )
{
case 0:
return “PROXY proxy1:80″;
break;
case 1:
return “PROXY proxy2:80″;
break;
case 2:
return “PROXY proxy3:80″;
break;
case 3:
return “PROXY proxy4:80″;
break;
case 4:
return “PROXY proxy5:80″;
break;
}
}

這個示例中用了一個js中常見的隨機數選擇方法實現了在5個代理伺服器中隨機選擇,這條函式的作者用意大概是平衡伺服器使用量,但更重要是的是給我們打開了一個思路,讓一些常見的js函式加入到PAC檔案中或許能寫出一些精彩有趣的函式來。

可用函式

以下列舉的是可用於FindProxyForURL()函式體中的條件函式,這些函式的具體用法如果大家感興趣請查閱網際網路,這裡就不詳細介紹了:

基於主機名的函式:

isPlainHostName()  dnsDomainIs()  localHostOrDomainIs()  isResolvable()  isInNet()

相關的實用程式函式:

dnsResolve()  myIpAddress()  dnsDomainLevels()

基於URL/主機名的條件:

shExpMatch()

基於時間的條件:

weekdayRange()  dateRange()  timeRange()  isPlainHostName(host)


-----另外一篇文章-----

因為工作需要,經常需要在家裡和辦公場所使用同一臺電腦,由於家裡不需要設定瀏覽器的代理,而在辦公場所就需要設定。所以每次都需要修改,換WINDOWS7之前一直使用IBM版本的Access Connections(以下簡稱AC)來切換網路設定,很強大,很方便,但遺憾的是IBM版本的AC不支援WIN7,而ThinkpAdvantage系列的AC是有名的臭名昭著——會導致開機緩慢。下了幾個IP切換軟體,卻都少有IE代理切換功能,IPHELPER倒是提供IE代理配置,但公司網中使用的是“IE自動配置指令碼”,設定了對內網訪問時不使用代理,連線外網時才使用代理。無奈之下深入研究了一下這個IE自動配置指令碼的原理,發現原來它就可以實現我所需要的功能(當然IP地址切換功能除外,但提供這個功能的小軟體海了去了~),使用IE自動配置指令碼,就可以不用每次在單位和家之間手動設定IE代理了~只需要加上一行程式碼即可~(當然這行程式碼來之不易,其實學過計算機二級考過了C語言的童鞋們只要靜下心來看一看下面的介紹,應該就對IE自動配置指令碼一清二楚了~)

1. 什麼是IE自動配置指令碼

IE自動配置指令碼起的作用就是,當IE訪問網頁的時候會根據指令碼檔案裡面界定的內容來訪問。比方說,你在指令碼檔案裡面限定了訪問某些IP使用某個代理的時候,訪問另外一些IP使用另外的代理,這就很方便通過指令碼檔案來完成。 

2. 如何建立、編輯IE自動配置指令碼

1)建立:開啟WINDOWS自帶的記事本,編輯好程式碼後另存為“.PAC”格式

2)編輯:使用WINDOWS自帶的記事本即可。

3. 如何編寫IE自動配置指令碼 

最簡單的格式就是包含一個叫FindProxyForURL的JScript函式,IE通過傳入兩個變數來呼叫這個函式,一個是使用者瀏覽的地址URL全路經,一個是這個URL中的主機名部分(host)。

這個FindProxyForURL函式有三種可能的字串返回值,一是"DIRECT",就是直接連線,不通過代理;二是"PROXY proxyaddr:port",其中proxyaddr和port分別是代理的地址和代理的埠;三是"SOCKS socksaddr:port",其中socksaddr和port分別是socks代理的地址和埠,一個自動代理檔案可以是多個選擇的組合,其中用分號(;)隔開,如:

      function FindProxyForURL(url,host)

      {

      if (host == "www.mydomain.com")

      return "DIRECT";

      return "PROXY myproxy:80;

      PROXY myotherproxy:8080;

      DIRECT";

      }

把以上程式碼另存為proxy.pac的檔案,如:c:/proxy.pac,然後在IE的選單裡"工具"->"INTEL選項"->"連線"->區域網設定->把使用自動配置指令碼選上,然後在位址列填入file://c:/proxy.pac,注意file後是兩斜槓,要使設定生效,需要關閉IE再重新開啟.

現在我們介紹下這個proxy.pac指令碼檔案,指令碼的語法是js語法,js的內建函式可以使用,要實現自動配置代理,需要實現FindProxyForURL這個函式,其引數url代表要訪問的連線,host代表要訪問連線的主機名,該函式有三個返回引數( direct:直接連線,proxy IP:PORT,socket IP:PORT), 返回結果大小寫不敏感.

PAC指令碼另外一個重要的應用是多臺代理伺服器並存的情況下,通過pac指令碼的控制,可以實現如下目標:

使使用者隨機選擇使用多臺代理伺服器中的任意一臺來達到流量負載均衡的目的;

使管理員通過PAC指令碼控制使用者使用和不使用某臺代理伺服器,這樣可以空出時間對代理伺服器進行維護;

讓伺服器工作在主備模式,當主伺服器宕機時,會自動切換到其它備用伺服器而不會中斷服務;

根據訪問目的地的不同,自動選擇最佳代理伺服器。

下面我們介紹幾個常用的PAC函式,並舉便說明:

   <1 isPlainHostName(host),判斷是否為本地主機,例如以http://myservername/的方式訪問,則是直接連線,否則使用代理

        function FindProxyForURL(url, host)

        {

          if (isPlainHostName(host))

            return "DIRECT";

          else

            return "PROXY proxy:80";

        }

    <2 dnsDomainIs(host, "")、localHostOrDomainIs(host, ""),判斷所訪問主機是否屬於某個域和某個域名,例如屬於.company.com域的主機名,www.company.com和home.company.com的直接連線,否則使用代理訪問。

         function FindProxyForURL(url, host)

        {

          if ((isPlainHostName(host) ||

             dnsDomainIs(host, ".company.com")) &&

            !localHostOrDomainIs(host, "www.company.com") &&

            !localHostOrDomainIs(host, "home.company.com"))

            return "DIRECT";

          else

            return "PROXY proxy:80";

        }

   <3 isResolvable(host),判斷被訪問主機名能否被解析.例子演示主機名能否被dns伺服器解析,如果能直接訪問,否則就通過代理訪問。

        function FindProxyForURL(url, host)

        {

          if (isResolvable(host))

            return "DIRECT";

          else

            return "PROXY proxy:80";

        }

   <4 isInNet(host, "", ""),判斷IP是否在某個子網內.例子演示訪問IP段的主頁不使用代理。

      function FindProxyForURL(url, host)

      {

          if (isInNet(host, "10.0.0.0", "255.255.0.0"))

            return "DIRECT";

          else

            return "PROXY proxy:80";

      }

   <5 shExpMatch(host, ""),判斷被訪問主機名是否符合某一正則表示式.本例演示根據主機域名來改變連線型別,本地主機、*.edu、*.com分別用不同的連線方式。

        function FindProxyForURL(url, host)

        {

          if (isPlainHostName(host))

            return "DIRECT";

          else if (shExpMatch(host, "*.com"))

            return "PROXY comproxy:80";

          else if (shExpMatch(host, "*.edu"))

            return "PROXY eduproxy:80";

          else

            return "PROXY proxy:80";

        }

   <6 url.substring(),取URL字串的子串.本例演示根據不同的協議來選擇不同的代理,http、https、ftp、gopher分別使用不同的代理。

        function FindProxyForURL(url, host)

        {

            if (url.substring(0, 5) == "http:") {

              return "PROXY proxy:80";

            }

            else if (url.substring(0, 4) == "ftp:") {

              return "PROXY fproxy:80";

            }

            else if (url.substring(0, 7) == "gopher:") {

              return "PROXY gproxy";

            }

            else if (url.substring(0, 6) == "https:") {

              return "PROXY secproxy:8080";

            }

            else {

              return "DIRECT";

            }

        }

   <7 dnsResolve(host),解析地址.本例演示判斷訪問主機是否某個IP,如果是就使用代理,否則直接連線。

      function FindProxyForURL(url, host)

      {

         if (dnsResolve(host) == "166.111.8.237") {

              return "PROXY secproxy:8080";

            }

            else {

              return "PROXY proxy:80";

            }

      }

      <8 myIpAddress(),返回自己的IP地址.本例演示判斷本地IP是否某個IP,如果是就使用代理,否則直接使用連線。

        function FindProxyForURL(url, host)

        {

            if (myIpAddress() == "10.1.1.1") {

              return "PROXY proxy:80";

            }

            else {

              return "DIRECT";

            }

        }

     <9 dnsDomainLevels(host),返回被訪問主機域名級數.本例演示訪問主機的域名級數是幾級,就是域名有幾個點,如果域名中有點,就通過代理訪問,否則直接連線。

        function FindProxyForURL(url, host)

        {

            if (dnsDomainLevels(host) > 0) { // if number of dots in host > 0

              return "PROXY proxy:80";

            }

             return "DIRECT";

        }

      <10 weekdayRange(),判斷當前日期日否在某一星期段.本例演示當前日期的範圍來改變使用代理,如果是GMT時間週三到週六,使用代理連線,否則直接連線。

        function FindProxyForURL(url, host)

        {

          if(weekdayRange("WED", "SAT", "GMT"))

           return "PROXY proxy:80";

          else

           return "DIRECT";

        }

      <11 最後一個例子是演示隨機使用代理,這樣可以好好利用代理伺服器。

      function FindProxyForURL(url,host)

      {

            return randomProxy();

      }

      function randomProxy()

      {

           switch( Math.floor( Math.random() * 5 ) )

           {

               case 0:

                   return "PROXY proxy1:80";

                   break;

               case 1:

                   return "PROXY proxy2:80";

                   break;

               case 2:

                   return "PROXY proxy3:80";

                   break;

               case 3:

                   return "PROXY proxy4:80";

                   break;

               case 4:

                   return "PROXY proxy5:80";

                   break;

           }   

      }

最後,我解決開篇問題的方法如下:(家裡的網段IP地址為192.168.1.101,不設代理,單位需要使用代理TEST.PROXY.COM:8080,但對公司內網除外)

function FindProxyForURL(url,host)

{

if (myIpAddress() == "192.168.1.101") return "DIRECT";

else if ( isInNet(host, "XX.0.0.0", "255.0.0.0" ) ) return "DIRECT";

else if ( dnsDomainIs(host,"company") || dnsDomainIs(host,"XXXX.com") ) return "DIRECT";

else if ( dnsDomainIs(host,".CLIENT") || dnsDomainIs(host,".XXXX") ) return "DIRECT";

else return "PROXY XXX.proxy.com:8080";

}

注:紅色粗體字均為個人設定,按需求修改。

將這些內容存為c:/myproxy.pac然後在IE屬性->連線->區域網設定->勾選使用自動配置指令碼->填入file://c:/myproxy.pac->確定,即可實現自動判斷場所上網了,當然,這個檔案也可以存在網站上,當然,這時地址就應該為類似http://x.x.x.x/......../proxy.pac的格式了。如果你是一個域管理員,你也可以通過更改組策略的方式把這個地址設定成IE的自動配置指令碼.