Sun Java System Web Proxy Server 4.0.4 管理指南

手動建立自動配置檔案

本小節說明如何手動建立自動配置檔案。

代理伺服器自動配置檔案是以用戶端 JavaScript 所撰寫。每個檔案都包含一個名為 FindProxyForURL() 的 JavaScript 函數,決定瀏覽器針對各個 URL 使用哪個代理伺服器 (如果存在)。瀏覽器會傳送兩個參數給 JavaScript 函數:目標原始伺服器的主機名稱,以及它嘗試取得的 URL。JavaScript 函數會傳回一個值給 Navigator,告知 Navigator 如何繼續。下節說明函數語法與可能的傳回值。

FindProxyForURL() 函數

FindProxyFor() URL 函數的語法是:

function FindProxyForURL(url, host){   ...}

對於瀏覽器所存取的每個 URL,它會傳送 urlhost 參數,並以下列方式呼叫函數:

ret = FindProxyForURL(url, host);

url 是要透過瀏覽器存取的完整 URL。

host 是從要存取之 URL 擷取的主機名稱。這只是為了方便;它其實與 :// 與第一個 :或其後 / 之間的字串相同。此參數不包含連接埠號。如果有需要,可以從 URL 擷取。

ret (傳回值) 是說明配置的字串。

函數傳回值

自動配置檔案包含函數 FindProxyForURL()。此函數使用用戶端主機名稱與要存取的 URL 做為參數。此函數會傳回單一字串,告知瀏覽器如何繼續。若該字串為空,則表示不使用任何代理伺服器。該字串可包含下表顯示任何數量的基本元素,每個基本元素以分號分隔。

表 17–2 FindProxyForURL() 傳回值

傳回值 

導致的瀏覽器動作 

DIRECT

直接與伺服器連線,而不透過任何代理伺服器。 

PROXY host:port

使用指定的代理伺服器與連接埠號。若使用分號分隔多個值,則會使用第一個代理伺服器。若該代理伺服器故障,則會使用下一個代理伺服器,以此類推。 

SOCKS host:port

使用指定的 SOCKS 伺服器。若使用分號分隔多個值,則會使用第一個代理伺服器。若該代理伺服器失敗,則會使用下一個代理伺服器,以此類推。 

若瀏覽器遇到無法使用的代理伺服器,瀏覽器會在 30 分鐘後自動重試先前無回應的代理伺服器,然後 1 小時後再重試,以此類推 (重試間隔為 30 分鐘)。因此,若您暫時關閉某個代理伺服器,在該代理伺服器重新啟動後,您的用戶端會在 30 分鐘內繼續使用該代理伺服器。

若所有代理伺服器皆已當機,且未指定 DIRECT 傳回值,瀏覽器將會要求使用者決定是否要讓瀏覽器暫時忽略代理伺服器,而嘗試直接連線。瀏覽器將會詢問是否要在 20 分鐘之後重試代理伺服器,然後 20 分鐘之後再詢問一次,以此類推 (詢問間隔為 20 分鐘)。

在以下範例中,傳回值將要求瀏覽器使用連接埠 8080 上名為 w3proxy.example.com 的代理伺服器。若該代理伺服器無法使用,瀏覽器會使用連接埠為 8080 上名為 proxy1.example.com 的代理伺服器。

PROXY w3proxy.example.com:8080; PROXY proxy1.example.com:8080

在下一個範例中,主代理伺服器是 w3proxy.example.com:8080 。若該代理伺服器無法使用,瀏覽器會使用 proxy1.example.com:8080。若兩個代理伺服器都無法使用,則瀏覽器會直接存取伺服器。在 20 分鐘過後,瀏覽器會詢問使用者是否要重試第一個代理伺服器。

PROXY w3proxy.example.com:8080; PROXY proxy1.example.com:8080; DIRECT

JavaScript 函數與環境

JavaScript 語言具有數個預先定義的函數與環境條件,在使用代理伺服器時非常有用。這些函數都會檢查是否與某特定條件相符,並傳回 true 或 false 值。相關公用程式函數則為例外,因為它們會傳回 DNS 主機名稱或 IP 位址。您可以在主 FindProxyForURL () 函數中使用這些函數,以決定要傳送給瀏覽器的傳回值。本章稍後的範例將提供使用這些函數的方式。

本小節會說明每個函數或環境條件。瀏覽器與代理伺服器整合時適用的函數和環境條件為:

以主機名稱為基礎的函數

以主機名稱為基礎的函數可讓您使用主機名稱或 IP 位址,來決定要使用的代理伺服器 (如果存在)。

dnsDomainIs()(host, domain)

dnsDomainIs()() 函數可偵測 URL 主機名稱是否屬於指定 DNS 網域。當您將瀏覽器配置成針對本機網域不使用代理伺服器時,此函數非常有用,如範例 1:除本地主機之外所有伺服器都使用代理伺服器範例 2:為防火牆外的本地伺服器使用代理伺服器中所述。

在根據 URL 所屬的 DNS 網域,從代理伺服器群組中選取要用來接收請求之代理伺服器時,若您使用多個代理伺服器來達成負載平衡,此函數也非常有用。例如,若您的負載平衡配置是將包含 .edu 的 URL 導向到一個代理伺服器,並將包含 .com 的 URL 導向到另一個代理伺服器,則可以使用 dnsDomainIs()() 來檢查 URL 主機名稱。

參數

host 是來自 URL 的主機名稱。

domain 是測試主機名稱時所依據的網域名稱。

傳回值

true 或 false

範例

下列敘述為 true:

dnsDomainIs("www.example.com", ".example.com")

下列敘述為 false:

dnsDomainIs("www", ".example.com") dnsDomainIs("www.mcom.com", 
	".example.com")

isInNet()(host, pattern, mask)

isInNet()() 函數可讓您將 URL 主機名稱解析為 IP 位址,並測試它是否屬於遮罩所指定的子網路。這與 SOCKS 使用的 IP 位址式樣屬於相同類型。請參閱範例 4:直接連線到子網路

參數:

host 為 DNS 主機名稱或 IP 位址。若傳送的是主機名稱,此函數會將它解析為 IP 位址。

pattern 是以點分隔的 IP 位址式樣

mask 是 IP 位址式樣遮罩,決定應該比對 IP 位址的哪個部分。值 0 表示忽略;255 表示相符。若主機的 IP 位址符合指定的 IP 位址式樣,則此函數會傳回 true。

傳回值

true 或 false

範例

只有當主機的 IP 位址與 198.95.249.79 完全相符時,此敘述才為 true:

isInNet(host, "198.95.249.79", "255.255.255.255")

只有當主機的 IP 位址與 198.95.* .* 完全相符時,此敘述才為 true: isInNet(host, "198.95.0.0", "255.255.0.0")

isPlainhost name()(host)

isPlainhost name()() 函數會偵測所請求 URL 中的主機名稱,是一般主機名稱還是完全合格的網域名稱。當您想要讓瀏覽器直接連線到本地伺服器時,此函數非常有用,如範例 1:除本地主機之外所有伺服器都使用代理伺服器範例 2:為防火牆外的本地伺服器使用代理伺服器中所述。

參數

host 是來自 URL 的主機名稱,僅在主機名稱沒有網域名稱 (沒有以點分隔的區段) 時排除連接埠號。

傳回值

host 為本機時傳回 true;host 為遠端時傳回 false

範例

isPlainhost name("host")

hostwww 之類的字串,則此函數會傳回 true。若 host 是 www. example.com 之類的字串,則此函數會傳回 false。

isResolvable()(host)

若防火牆內的 DNS 只能識別內部主機,您可以使用 isResolvable()() 函數來測試主機名稱屬於內部網路還是外部網路。透過使用此函數,您可以配置瀏覽器針對內部伺服器使用直接連線,而只針對外部伺服器使用代理伺服器。在防火牆內的內部主機可以解譯其他內部主機的 DNS 網域名稱,但無法解析所有外部主機的站點中,此函數非常有用。isResolvable()() 函數會查閱 DNS,嘗試將主機名稱解析為 IP 位址。請參閱範例 3:只會為無法解譯的主機使用代理伺服器

參數

host() 是來自 URL 的主機名稱。

傳回值

若此函數可以解析主機名稱,會傳回 true;否則會傳回 false

範例

isResolvable("host")

host()www 之類的字串,且可透過 DNS 解析,則此函數會傳回 true。

localHostOrDomainIs()(host, hostdom)

localHostOrDomainIs()() 函數指定可能會由完全合格的網域名稱或一般主機名稱存取的本地主機。請參閱範例 2:為防火牆外的本地伺服器使用代理伺服器

若主機名稱與指定的主機名稱完全相符,或與不合格主機名稱相符的主機名稱中沒有網域名稱部分,則 localHostOrDomainIs()() 函數會傳回 true

參數

host 是來自 URL 的主機名稱。

hostdom 是要比對之完全合格的主機名稱。

傳回值

true 或 false

範例

以下敘述為 true (完全相符):

localHostOrDomainIs("www.example.com", "www.example.com")

以下敘述為 true (主機名稱符合,未指定網域名稱):

localHostOrDomainIs("www", "www.example.com")

以下敘述為 false (網域名稱不相符):

localHostOrDomainIs("www.mcom.com", "www.example.com")

以下敘述為 false (主機名稱不相符):

localHostOrDomainIs("home.example.com", "www.example.com")

公用程式函數

您可以使用公用程式函數找出網域層級、執行瀏覽器的主機,或主機的 IP 位址。

dnsDomainLevels()(host)

dnsDomainLevels()() 函數可找出 URL 主機名稱中的 DNS 層級數目 (點的數目)。

參數

host 是來自 URL 的主機名稱。

傳回值

DNS 網域層級的數目 (整數)。

範例

dnsDomainLevels("www") 傳回 0。

dnsDomainLevels("www.example.com") 傳回 2。

dnsResolve()(host)

dnsResolve()() 函數會解析指定主機 (通常是來自 URL) 的 IP 位址。若 JavaScript 函數必須執行的式樣比對程序,比現有函數的功能更進階,則此函數就非常有用。

參數

host 是要解析的主機名稱。將指定的 DNS 主機名稱解析為 IP 位址,並以字串傳回 (以點分隔的格式)。

傳回值

字串值 (由以點分隔的四組數字所組成的 IP 位址)

範例

以下範例將傳回字串 198.95.249.79

dnsResolve("home.example.com")

myIpAddress()()

當 JavaScript 函數必須根據執行瀏覽器的主機而有不同的運作方式時,myIpAddress()() 函數就非常有用。此函數會傳回執行瀏覽器之電腦的 IP 位址。

傳回值

字串值 (由以點分隔的四組數字所組成的 IP 位址)

範例:

若您是在 home.example.com 電腦上執行 Navigator,以下範例會傳回字串 198.95.249.79

myIpAddress()

以 URL/主機名稱為基礎的條件

您可比對主機名稱或 URL 以達到負載平衡和路由的目的。

shExpMatch()(str, shexp)

shExpMatch()() 函數會比對 URL 主機名稱或 URL 本身。此函數的主要用途是負載平衡,以及使用智慧型方式將 URL 路由至不同的代理伺服器。

參數

str 是要比較的任何字串 (例如,URL 或主機名稱)。

shexp 是比較時所依據的 shell 表示式。

若字串與指定的 shell 表示式相符,則此表示式會傳回 true。請參閱範例 6:使用 shExpMatch()() 平衡代理伺服器的負載

傳回值

true 或 false

範例

第一個範例會傳回 true。第二個範例會傳回 false。

shExpMatch("http://home.example.com/people/index.html",
            ".*/people/.*")
shExpMatch("http://home.example.com/people/yourpage/index.html",
            ".*/mypage/.*")

以時間為根據的條件

您可以讓 FindProxyForURL 函數根據日期、時間或一週中的日期,有不同的運作方式。

dateRange() (day, month, year...)

dateRange()() 函數會偵測特定日期或日期範圍,例如 1996 年 4 月 19 日到 1996 年 5 月 3 日。若要讓 FindProxyForURL() 函數根據星期幾而有不同的運作方式 (例如,需要針對其中一個代理伺服器定期排程停機維護時間),此函數就非常有用。

您可以使用數種方式指定日期範圍:

dateRange(day)dateRange(day1, day2)dateRange(mon)dateRange(month1, month2)dateRange(year)dateRange(year1, year2)dateRange(day1, month1, day2, month2)dateRange(month1, year1, month2, year2)dateRange(day1, month1, year1, day2, month2, year2)dateRange(day1, month1, year1, day2, month2, year2, gmt)

參數

day 是 1 到 31 之間的整數,代表每月中的第幾天。

month 必須是下列其中一個月份字串:JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC

year 是四位整數的年份 (例如,1996)。

gmt 可以使用「GMT」字串表示,代表應以格林威治標準時間來比較時間,也可以留白表示使用本地時區。GMT 參數也可以指定於任何呼叫設定檔中,它始終做為最後一個參數。若在每個種類 (日、月、年) 中僅指定單一值,則此函數只在與指定值相符的日期傳回 true 值。若指定兩個值,則從第一個指定時間到第二個指定時間之間都會傳回 true 結果值。

範例

此敘述在每月第一天 (本地時區) 會傳回 true:dateRange(1)

此敘述在每月第一天 (格林威治標準時間) 會傳回 true:dateRange(1, "GMT")

此敘述在每月的上半月都會傳回 true:dateRange(1, 15)

此敘述在每年 12 月 24 日會傳回 true:dateRange(24, "DEC")

此敘述在 1995 年 12 月 24 日會傳回 true:dateRange(24, "DEC", 1995)

此敘述在每年第一季都會傳回 true:dateRange("JAN", "MAR")

此敘述在每年 6 月 1 日到 8 月 15 日都會傳回 true: dateRange(1, "JUN", 15, "AUG")

此敘述在 1995 年 6 月 1 日到 1995 年 8 月 15 日都會傳回 true:dateRange(1, "JUN", 15, 1995, "AUG", 1995)

此敘述在 1995 年 10 月到 1996 年 3 月都會傳回 true:dateRange("OCT", 1995, "MAR", 1996)

此敘述在 1995 年整年都會傳回 true:dateRange(1995)

此敘述在 1995 年初到 1997 年末都會傳回 true:dateRange(1995, 1997)

timeRange (hour, minute, second...)

timeRange() 函數會偵測一天中的特定時間或時間範圍,例如下午 9 點到上午 12 點。若要讓 FindProxyForURL() 函數根據不同時間而有不同的運作方式,此函數非常有用。

timeRange(hour)timeRange(hour1, hour2)timeRange(hour1, min1, hour2, min2)timeRange(hour1, min1, sec1, hour2, min2, sec2)

參數:

hour 是小時,介於 0 到 23 之間。0 是午夜,23 是下午 11:00 點。

min 是分鐘,介於 0 到 59 之間。

sec 是秒鐘,介於 0 到 59 之間。

gmt 可以是 GMT 字串 (表示 GMT 時區) 或未指定 (表示本地時區)。此參數可搭配每個參數設定檔使用,而且永遠是最後一個參數。

傳回值

true 或 false

範例:

此敘述在中午到下午 1:00 之間都會傳回 true:timerange(12, 13)

此敘述在中午到下午 12:59 (GMT) 之間都會傳回 true:timerange(12, "GMT")

此敘述在上午 9:00 到下午 5:00 之間都會傳回 true:timerange(9, 17)

此敘述在午夜與午夜過後三十秒之間都會傳回 true:timerange(0, 0, 0, 0, 0, 30)

weekdayRange()(wd1, wd2, gmt)

weekdayRange() 函數會偵測一週內的特定日期或一週內的日期範圍,例如星期一到星期五。若要讓 FindProxyForURL 函數根據星期幾而有不同的運作方式,此函數非常有用。

參數

wd1wd2 皆為下列其中一個星期幾字串:SUN MON TUE WED THU FRI SAT

gmt 可以是 GMT (表示格林威治標準時間) 或未指定 (表示本地時間)。

只有第一個參數 wd1 是必要參數。您可以忽略 wd2gmt,或同時忽略兩者。

若只指定一個參數,此函數在參數所代表的星期幾當天會傳回 true。若將字串 GMT 指定為第二個參數,就會以 GMT 表示時間。否則,會以您的本地時區表示時間。

wd1wd2 皆已定義,而當天介於一週內指定的這兩天之間時,此條件為 true。當作界線的這兩天也算在內。參數的順序非常重要;“MON,” “WED” 是指星期一到星期三,但 “WED,” “MON 是指星期三到下個星期一。

範例

此敘述在星期一到星期五 (本地時區) 之間會傳回 true。weekdayRange("MON", "FRI")

此敘述在星期一到星期五 (格林威治標準時間) 之間會傳回 true。 weekdayRange("MON", "FRI", "GMT")

此敘述在星期六 (本地時間) 會傳回 true。weekdayRange("SAT")

此敘述在星期六 (格林威治標準時間) 會傳回 true。weekdayRange("SAT", "GMT")

此敘述在星期五到星期一之間會傳回 true (順序非常重要) weekdayRange("FRI", "MON")

函數範例

本小節提供 JavaScript 函數的詳細範例。

範例 1:除本地主機之外所有伺服器都使用代理伺服器

在此範例中,瀏覽器會直接連線到未完全合格的所有主機,以及本機網域中的所有主機。存取其他主機時,則會透過名為 w3proxy.example .com:8080 的代理伺服器。


備註 –

若該代理伺服器當機,則會自動進行直接連線。


    function FindProxyForURL(url, host)
    {
        if (isPlainhost name(host) ||
            dnsDomainIs(host, ".example.com") ||
            dnsDomainIs(host, ".mcom.com"))
            return "DIRECT";
        else
            return "PROXY w3proxy.example.com:8080; DIRECT";
    }

範例 2:為防火牆外的本地伺服器使用代理伺服器

此範例類似範例 1:除本地主機之外所有伺服器都使用代理伺服器,但它會針對防火牆外部的本地伺服器使用代理伺服器。若主機 (例如,主 Web 伺服器) 屬於本機網域但位於防火牆外部,而且只能夠透過代理伺服器存取,則可以使用 localHostOrDomainIs()() 函數來處理那些異常:

    function FindProxyForURL(url, host)
    {
        if ((isPlainhost name(host) ||
        dnsDomainIs(host, ".example.com")) &&
        !localHostOrDomainIs(host, "www.example.com") &&
        !localHostOrDoaminIs(host, "merchant.example.com"))
            return "DIRECT";
        else
            return "PROXY w3proxy.example.com:8080; DIRECT";
    }

此範例會針對所有主機使用代理伺服器,但 example.com 網域中的本地主機除外。主機 www.example.commerchant.example.com 也會透過代理伺服器存取伺服器。

妥善指定異常的順序可增加效率:localHostOrDomainIs()() 函數只會針對位於本機網域中的 URL 執行,而不會針對每個 URL 執行。請特別注意 and 表示式之前、or 表示式周圍的括弧。

範例 3:只會為無法解譯的主機使用代理伺服器

此範例適用於內部 DNS 只能解析內部主機名稱的環境。其目的是只為無法解析的主機使用代理伺服器。

    function FindProxyForURL(url, host)
    {
        if (isResolvable(host))
                return "DIRECT";
            else
                return "PROXY proxy.mydomain.com:8080";
    }

使用此範例中的配置時,每次都需要經過 DNS 查找。因此,您可能需要搭配其他規則使用此範例,以便僅在其他規則沒有結果時才使用 DNS 查找。

    function FindProxyForURL(url, host)
    {
        if (isPlainhost name(host) ||
            dnsDomainIs(host, ".mydomain.com") ||
            isResolvable(host))
            return "DIRECT";
        else
            return "PROXY proxy.mydomain.com:8080";
    }

範例 4:直接連線到子網路

在此範例中,會直接連線到指定子網路中的所有主機。其他主機則會經過代理伺服器。

    function FindProxyForURL(url, host)
    {
        if (isInNet(host, "198.95.0.0", "255.255.0.0"))
            return "DIRECT";
        else
            return "PROXY proxy.mydomain.com:8080";
    }

在此範例中,您可以在開頭增加備援規則,以降低使用 DNS 的頻率:

    function FindProxyForURL(url, host)
    {
        if (isPlainhost name(host) ||
            dnsDomainIs(host, ".mydomain.com") ||
            isInNet(host, "198.95.0.0", "255.255.0.0"))
            return "DIRECT";
        else
            return "PROXY proxy.mydomain.com:8080";
    }

範例 5:使用 dnsDomainIs()() 平衡代理伺服器的負載

此範例比上述範例複雜。此範例使用四個代理伺服器,而其中一個是做為其他伺服器的緊急備用伺服器。若任何三個代理伺服器當機,會由第四個代理伺服器接手。其他三個代理伺服器會根據 URL 式樣分擔負載,以使快取效果更好。三個伺服器上只會為所有文件保存一份副本,而不是各自都有一份副本。負載的分擔方式如下表所示。

表 17–3 平衡代理伺服器的負載

代理伺服器 

目的 

#1 

.com 網域

#2 

.edu 網域

#3 

其他所有網域 

#4 

緊急備用 

存取本機網域時皆應使用直接存取。所有代理伺服器都是在連接埠 8080 上執行。您可以使用 + 運算子來鏈結字串。

function FindProxyForURL(url, host)
{
    if (isPlainhost name(host) || dnsDomainIs(host, ".mydomain.com"))
        return "DIRECT";

    else if (dnsDomainIs(host, ".com"))
        return "PROXY proxy1.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";

    else if (dnsDomainIs(host, ".edu"))
        return "PROXY proxy2.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";

    else
        return "PROXY proxy3.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";
}

範例 6:使用 shExpMatch()() 平衡代理伺服器的負載

此範例基本上與範例 5:使用 dnsDomainIs()() 平衡代理伺服器的負載相同,但範例 5 使用 dnsDomainIs()(),而此範例使用 shExpMatch()()

    function FindProxyForURL(url, host)
    {
    if (isPlainhost name(host) || dnsDomainIs(host, ".mydomain.com"))
        return "DIRECT";
    else if (shExpMatch(host, "*.com"))
        return "PROXY proxy1.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";
    else if (shExpMatch(host, "*.edu"))
        return "PROXY proxy2.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";
    else
        return "PROXY proxy3.mydomain.com:8080; " +
              "PROXY proxy4.mydomain.com:8080";
    }

範例 7:針對特定協定使用代理伺服器

您可以為特定協定設定代理伺服器。您可以在 FindProxyForURL()() 函數中使用大部分標準 JavaScript 功能。例如,若要根據協定設定不同的代理伺服器,可以使用 substring()() 函數。

    function FindProxyForURL(url, host)
    {
        if (url.substring(0, 5) == "http:") {
            return "PROXY http-proxy.mydomain.com:8080";
        }
        else if (url.substring(0, 4) == "ftp:") {
            return "PROXY ftp-proxy.mydomain.com:8080";
        }
        else if (url.substring(0, 7) == "gopher:") {
            return "PROXY gopher-proxy.mydomain.com:8080";
        }
        else if         (url.substring(0, 6) == "https:" ||
                url.substring(0, 6) == "snews:") {
            return "PROXY security-proxy.mydomain.com:8080";
        }
        else {
            return "DIRECT";
        }
    }

您也可以使用 shExpMatch()() 函數來完成此配置,例如:

    ...
    if (shExpMatch(url, "http:*")) {
        return "PROXY http-proxy.mydomain.com:8080;
    }
    ...