直播中
圖4-24 使用Server.MapPath的屏幕
單擊該按鈕重新裝載這個(gè)網(wǎng)頁(yè),執(zhí)行該方法并在頂部顯示結(jié)果,在下部顯示原頁(yè)面的其余部分,如圖4-25所示:
圖4-25 顯示Server.MapPath的結(jié)果
(1) 示例網(wǎng)頁(yè)代碼的功能
處理這個(gè)過(guò)程的代碼是與前面在相似的示例文件中已經(jīng)使用過(guò)的代碼十分相似。
在該頁(yè)面頂部的ASP腳本區(qū)域中,對(duì)單擊的按鈕的名字進(jìn)行檢查。在這種情況下,該按鈕的名字將是cmdMapPath,簡(jiǎn)單地把相匹配的文本框中的值txtMapPath傳送給Server.MapPath方法,并顯示得到的結(jié)果:
If Len(Request.Form(“cmdMapPath”)) Then
StrValue = Request.Form(“txtMapPath”)
Response.Write “<B>Results:</B><BR>Server.MapPath (“ & QUOT & strValue _
& QUOT & “ ) returned <B>” & QUOT & Server.MapPath(strValue) _
& QUOT & “</B><HR>”
End If
(2) MapPath和虛擬應(yīng)用程序目錄
注意,MapPath方法為/iishelp/default.htm文件獲取的結(jié)果在Web服務(wù)器目錄外,并在主winnt目錄的help目錄中。這清楚地證明了MapPath方法是非常有用的。
對(duì)于在缺省的Web網(wǎng)站目錄中的文件,其URL的路徑部分與物理路徑通常是相同的。例如,一個(gè)文件存儲(chǔ)在Web服務(wù)器上:
c:\InetPub\WWWRoot\yourfiles\thisfile.asp
如果安裝時(shí)已經(jīng)在缺省目錄中安裝了的Web根目錄,則URL如下:
http://yoursite.com/yourfiles/thisfile.asp
然而,IIS Help文件安裝在缺省Web網(wǎng)站目錄外的一個(gè)虛擬目錄中,所以用于對(duì)其進(jìn)行訪問(wèn)的URL和物理路徑之間沒(méi)有直接的關(guān)聯(lián)。只有通過(guò)使用Server.MapPath方法才能獲取真實(shí)的物理路徑。
4.3..6 使用Server對(duì)象格式化數(shù)據(jù)
當(dāng)前面討論演示SSI指令的網(wǎng)頁(yè)的代碼時(shí),碰巧遇到了使用HTML的一個(gè)老問(wèn)題。在一個(gè)HTML網(wǎng)頁(yè)中如何顯示HTML代碼?如果“照現(xiàn)在的樣子”使用,也就是在相應(yīng)的位置上使用所有的HTML字符,會(huì)被瀏覽器當(dāng)作HTML解釋和執(zhí)行。這樣當(dāng)下列內(nèi)容在瀏覽器中顯示時(shí):
This is the syntax of a <TABLE> element:
將不會(huì)顯示文本<TABLE>,因?yàn)闉g覽器將其作為一個(gè)數(shù)據(jù)表的一個(gè)開(kāi)始標(biāo)記,并照此來(lái)執(zhí)行。為了避免這種情況,必須把在HTML中非法或無(wú)效的所有字符轉(zhuǎn)換到等價(jià)的HTML字符實(shí)體(character entity)。多數(shù)常見(jiàn)的字符如表4-5所示:
表4-5 字符與等價(jià)的HTML實(shí)體的關(guān)系
字 符
等價(jià)的HTML實(shí)體
字 符
等價(jià)的HTML實(shí)體
<
<
>
>
&
&
“
"
©
©
®
®
所有的實(shí)體以&號(hào)開(kāi)始并以分號(hào)結(jié)束,是在一些語(yǔ)言中表明一個(gè)實(shí)體的標(biāo)準(zhǔn)方法的一部分,這些語(yǔ)言是基于SGML(標(biāo)準(zhǔn)化常規(guī)標(biāo)識(shí)語(yǔ)言)規(guī)則的,如HTML語(yǔ)言。
1. 數(shù)字的HTML實(shí)體等價(jià)字符串
注意最后一個(gè)例子,已經(jīng)注冊(cè)的商標(biāo)®是一個(gè)以“#”字符為前綴的數(shù)字值,而不是相應(yīng)含義的一個(gè)文本縮寫(xiě)(如copy對(duì)應(yīng)版權(quán)符號(hào)©)。具有一個(gè)大于126的ANSI代碼值的所有字符在HTML中被表示為十進(jìn)制字符的ANSI代碼,以為前綴,以分號(hào)為后綴。
事實(shí)上,需要留心的是使用數(shù)字實(shí)體等價(jià)字符串要優(yōu)先于一些較少被支持文本實(shí)體字符串。一個(gè)例子是商標(biāo)字符(™),該字符的實(shí)體等價(jià)字符串為“™”但不是所有瀏覽器(例如Navigator)都能識(shí)別這個(gè)字符串,這種情況下,將在網(wǎng)頁(yè)中顯示該實(shí)體字符串。相反,使用™在所有瀏覽器中都能很好地工作。
2. Server對(duì)象的HTMLEncode方法
把HTML轉(zhuǎn)換為文本是進(jìn)行有效顯示需要的,否則HTML會(huì)被瀏覽器當(dāng)成HTML來(lái)對(duì)待和執(zhí)行,這意味著必須對(duì)無(wú)效的字符進(jìn)行編碼,使其成為等價(jià)的HTML實(shí)體字符串。為管理這種轉(zhuǎn)換,Server對(duì)象提供了HTMLEncode方法。可以在本書(shū)提供的ASP Server Object示例網(wǎng)頁(yè)中練習(xí)使用這個(gè)方法。
簡(jiǎn)單地把一些文本輸入到HTMLEncode對(duì)應(yīng)的文本框中并單擊按鈕。示例中提供了一些真實(shí)的HTML作為缺省的文本,如圖4-26所示:
圖4-26 使用HTMLEncode方法的屏幕
重新載入該頁(yè)面時(shí),在該頁(yè)面的頂部顯示結(jié)果。HTMLEncode方法把尖括號(hào)轉(zhuǎn)換成了“<”和“>”,而且把雙引號(hào)轉(zhuǎn)換成為“";”,如圖4-27所示:
圖4-27 使用HTMLEncode方法1
(1) 示例網(wǎng)頁(yè)代碼的功能
關(guān)于得到的結(jié)果,有幾個(gè)有趣的地方。
首先,在方法名字后面的括號(hào)中已經(jīng)丟掉了<B>和</B>標(biāo)記,相應(yīng)增加了一個(gè)粗體文本部分。在網(wǎng)頁(yè)中顯示原有的值時(shí),<B>和</B>被當(dāng)成HTML提交了,所以<B>和</B>標(biāo)記消失了,相關(guān)內(nèi)容以粗體文本顯示。
可以十分容易地避免這種情況。事實(shí)上,這就是設(shè)計(jì)HTMLEncode方法的原因。原示例代碼如下:
…
Response.Write “Server.HTMLEncode (“ & QUOT & strValue & QUOT & “) returned”
…
現(xiàn)在所能做的就是把HTMLEncode方法應(yīng)用于正在輸出的值上:
…
strResult = Server.HTMLEncode(strValue)
Response.Write “Server.HTMLEncode (“ & QUOT & strResult & QUOT & “) returned”
現(xiàn)在輸出了一個(gè)十分有用的結(jié)果,如圖4-28所示:
圖4-28 使用HTMLEncode方法的結(jié)果2
現(xiàn)在已經(jīng)解決了不提交HTML而顯示HTML的問(wèn)題。但是如果要在HTML中顯示HTMLEncode方法的結(jié)果,而又不提交和處理這些結(jié)果,又會(huì)發(fā)生什么情況?為了解決這個(gè)問(wèn)題,要從HTMLEncode方法本身考慮:
This is <B>"bold"</B> text
上面的語(yǔ)句在HTML網(wǎng)頁(yè)中得不到同樣的顯示結(jié)果,這是因?yàn)镠TML字符實(shí)體將被瀏覽器處理和執(zhí)行,并顯示為實(shí)體所替代的字符。換句話說(shuō),得到的是:
This is <B>”bold”</B> text
我們沒(méi)有看到實(shí)體。為了避免這種情況,可兩次使用Server.HTMLEncode方法。這就把“&”號(hào)變換為“&”,這樣就得到了所需的顯示結(jié)果。示例網(wǎng)頁(yè)的這個(gè)部分的代碼是:
If Len(Request.Form(“cmdHTMLEncode”)) Then
strValue = Request.Form(“txtHTMLEncode”) ‘Get the value from the text box
strResult = Server.HTMLEncode(strValue) ‘HTMLEncode to convert <,> and “
strDisplay = Server.HTMLEncode(strResult) ‘Then again to convert & to &
Response.Write “<B>Results:</B><BR>Server.HTMLEncode (“ & QUOT & strResult _
& QUOT & “) returned <B>” & QUOT & strDisplay & QUOT _
& “</B><HR>”
End If
(2) HTMLEncode與HTML控件的缺省值
從上面可以看出,如果在一個(gè)HTML網(wǎng)頁(yè)中要顯示HTML代碼,而又不使之被作為HTML進(jìn)行處理和執(zhí)行,HTMLEncode方法是非常有用的。在大多數(shù)普通的ASP網(wǎng)頁(yè)中不大可能會(huì)遇到這種情況,除非使用包含有HTML的數(shù)據(jù)庫(kù)或其他數(shù)據(jù)源中的數(shù)據(jù),而又需要作為文本進(jìn)行顯示。
但是HTMLEncode方法真正有用的地方是,通過(guò)設(shè)置VALUE屬性預(yù)設(shè)頁(yè)面中文本類型的HTML控件的值。作為例子,可看一下已經(jīng)用于練習(xí)HTMLEncode方法的示例網(wǎng)頁(yè)的源程序。創(chuàng)建HTMLEncode對(duì)應(yīng)的文本框的HTML在HTML頁(yè)中定義如下:
…
<INPUT TYPE=”TEXT” NAME=”txtHTMLEncode” SIZE=”35”
VALUE=”This is <B>"bold"</B> text”>
…
這是“手工編碼”而不是使用Server.HTMLEncode方法。這里也只關(guān)心對(duì)雙引號(hào)進(jìn)行編碼而不關(guān)心對(duì)尖括號(hào)的編碼。為什么?這是因?yàn)槿绻麤](méi)有這樣做,該代碼將被讀為:
VALUE=”This is <B>”bold”</B> text”
而在這種情況中尖括號(hào)不會(huì)帶來(lái)問(wèn)題,未編碼的雙引號(hào)則會(huì)。在文本框中替換的實(shí)際值將是“This is <B>”,即它將在第二個(gè)雙引號(hào)字符處被截?cái)?。所以,在?chuàng)建預(yù)置控件值的頁(yè)面時(shí),應(yīng)該考慮使用HTMLEncode方法,以避免這些值被截?cái)啵?BR><%
strValue = Request.Form(“txtSomeValue”)
%>
…
<INPUT TYPE=”TEXT” NAME=”txtSomeValue”
VALUE=”<% = ServerEncode(“strValue”) %>”>
…
當(dāng)瀏覽器發(fā)送已經(jīng)被HTML編碼的一個(gè)控件的值給服務(wù)器時(shí),自動(dòng)進(jìn)行反向譯碼。即服務(wù)器使用Request集合中原來(lái)格式的數(shù)據(jù)。
3. 格式化UTL的數(shù)據(jù)
還有另外一種情況,就是經(jīng)常需要把一個(gè)文本字符串變換成能夠在Web網(wǎng)頁(yè)中使用的另外一種格式?,F(xiàn)代Web服務(wù)器和操作系統(tǒng)都十分友好地支持包含空格字符的文件名,但是我們所使用的URL可能包含有空格字符,由于HTTP使用的URL語(yǔ)法不允許有空格字符(和幾個(gè)其他字符),可能會(huì)出現(xiàn)麻煩。
另外一種更普遍的情況也會(huì)出現(xiàn)麻煩。當(dāng)把這些值作為QueryString集合的成員傳送給服務(wù)器時(shí),將被追加到URL的末尾(在一個(gè)問(wèn)號(hào)字符之后)。這種情況發(fā)生在<FORM>的METHOD屬性被設(shè)置為“GET”(或者是省略了METHOD屬性)的情況。換句話說(shuō),對(duì)于直接追加到URL上的值,都可能出現(xiàn)麻煩。這可能發(fā)生在<A>元素中:
<A HREF=http://myserver.com/mypage.asp?title=Instant Jscript>Instant Jscript</A>
一些瀏覽器(例如Internet Explorer)可以對(duì)此進(jìn)行處理,因?yàn)樗鼈冊(cè)诎袶TTP請(qǐng)求發(fā)送到服務(wù)器之前,自動(dòng)地執(zhí)行必要的轉(zhuǎn)換。然而,許多其他的瀏覽器不進(jìn)行這種轉(zhuǎn)換,并導(dǎo)致了URL通常在第一個(gè)空格或非法字符處被截?cái)?。這樣在Navigator中,上面給出的鏈接要求的網(wǎng)頁(yè)變?yōu)閔ttp://myserver.com/mypage.asp?title=Instant。在服務(wù)器上,title名字/值對(duì)的丟失部分會(huì)使代碼失敗。
考慮到HTTP協(xié)議定義的限制,必須從作為HTTP請(qǐng)求中的URL使用的字符串中刪除非法的字符(非法字符是所有那些ANSI代碼在126之上的字符和ANSI代碼在126以下的某些字符)。
ANSI代碼大于126的字符必須用百分號(hào)后跟十六進(jìn)制形式的ANSI代碼進(jìn)行替換。這樣,版權(quán)字符©變成%A9。ANSI代碼在126之下在URL中不合法的字符,同樣使用相應(yīng)的替代字符串;如表4-6所示:
表4-6 字符與HTTP/URL代替物的關(guān)系
字 符
HTTP/URL代替物
字 符
HTTP/URL代替物
空格
+
\
%5C
‘
%27
]
%5D
!
%21
^
%5E
#
%23
`
%60
$
%24
{
%7B
%
%25
|
%7C
&
%26
}
%7D
(
%28
+
%2B
)
%29
<
%3C
/
%2F
=
%3D
:
%3A
>
%3E
;
%3B
Chr(10)
忽略
[[/TD]
%5B
Chr(13) [TD]
%0D
4. Server對(duì)象的URLEncode方法
Server對(duì)象提供了可以用來(lái)把任意字符串轉(zhuǎn)換成相應(yīng)的合法HTTP URL的方法??梢岳檬纠W(wǎng)頁(yè)對(duì)這個(gè)名為URLEncode的方法進(jìn)行練習(xí),如圖4-29所示:
圖4-29 使用URLEncode方法的屏幕
這里,輸入的值作為URL是非法的,它包含了空格和ANSI代碼大于126的字符。對(duì)這個(gè)值,使用URLEncode方法的結(jié)果是所有的空格被替換成一個(gè)加號(hào),版權(quán)符號(hào)被替換為 %A9,如圖4-30所示:
圖4-30 使用URLEncode方法的結(jié)果
(1) 示例網(wǎng)頁(yè)代碼的功能
在示例網(wǎng)頁(yè)中,處理這個(gè)功能的代碼非常簡(jiǎn)單,僅僅檢查是否單擊了URLEncode方法對(duì)應(yīng)的按鈕,如果單擊了,把對(duì)應(yīng)的文本框中的值傳遞給Server.URLEncode方法并顯示結(jié)果:
If Len(Request.Form(“cmdURLEncode”)) Then
strValue = Request.Form(“txtURLEncode”)
Response.Write “<B>Results:</B><BR>Server.URLEncode (“ & QUOT & strValue _
& QUOT & “) returned <B>” & QUOT & Server.URLEncode(strValue) _
& QUOT & “</B><HR>”
End If
(2) 對(duì)HTML元素和其他鏈接使用URLEncode
URLEncode方法更普遍地用于把<A>元素或其他鏈接的值寫(xiě)到ASP網(wǎng)頁(yè)。例如,如果在查詢字符串中建立了一系列的鏈接,這;些鏈接包含來(lái)自一個(gè)數(shù)據(jù)庫(kù)的值,首先應(yīng)該對(duì)這個(gè)字符串使用Server.URLEncode方法:
<%
strValue = Request.Form(“txtSomeValue”)
‘Create the full URL for the link as an HTTP-legal string
strURL = http://mysite.com/books.asp?title= & Server.URLEncode(“strValue”)
‘Make sure we don’t have any non-legal HTML characters in the page text
strLink = Server.HTMLEncode(“strValue”)
%>
…
<A HREF=”<% = strURL %>”><% = strValue %></A>
…
如果放入字符串strValue的值包含標(biāo)題“Active Server Pages©”,將得到由這個(gè)代碼段創(chuàng)建的如下所示的HTML:
<A HREF=http://mysite.com/books.asp?title=Active+Server+Pages%A9>
Active Server Pages©</A>
注意,我們不僅僅使用Server.URLEncode方法來(lái)建立一個(gè)合法的URL字符串,而且還對(duì)鏈接的文本使用了Server.HTMLEncode方法,以確保把所有非法的字符轉(zhuǎn)換為合適的HTML等價(jià)實(shí)體。
和HTMLEncode方法一樣,不用反譯碼ASP網(wǎng)頁(yè)中的URL編碼值。IIS自動(dòng)地實(shí)現(xiàn)URL編碼字符串的轉(zhuǎn)換,該字符串在HTTP請(qǐng)求中轉(zhuǎn)換為它們?cè)雀袷?,使得它們?cè)趦?nèi)置對(duì)象中是可用的。
4.4 小結(jié)
在這一章中,通過(guò)在Web服務(wù)器上發(fā)生的處理過(guò)程,討論了為Web網(wǎng)頁(yè)提供動(dòng)態(tài)內(nèi)容所涉及的一些問(wèn)題。這些問(wèn)題的一部分不是直接地與ASP本身相關(guān),但對(duì)這些問(wèn)題的理解,將有助于理解基本的處理工作是如何進(jìn)行的。
本章介紹了IIS如何支持傳統(tǒng)的服務(wù)器端包含指令,有一些指令可能仍然是有用的。特別是,#exec指令對(duì)執(zhí)行系統(tǒng)命令以及集成原有的應(yīng)用程序都是有用的。同時(shí)也討論了一條特別的服務(wù)器端包含指令——#include語(yǔ)句,了解了在ASP網(wǎng)頁(yè)內(nèi)部使用這條命令的相關(guān)問(wèn)題。
然而,ASP Server對(duì)象占了本章的大部分。它提供了在ASP網(wǎng)頁(yè)內(nèi)管理服務(wù)器端處理過(guò)程的方法。在Web服務(wù)器和ASP的正確的環(huán)境中,它可用來(lái)創(chuàng)建其他對(duì)象、應(yīng)用程序或組件的實(shí)例。它同時(shí)也提供了一系列的方法,這些方法允許執(zhí)行其他的網(wǎng)頁(yè)或資源,以及以正確方式格式化信息,以便在ASP腳本和網(wǎng)頁(yè)中使用。 Server對(duì)象也帶來(lái)了一個(gè)新的ASP內(nèi)置對(duì)象:ASPError對(duì)象,它為腳本提供較好的錯(cuò)誤處理方法?,F(xiàn)在可以提供“正統(tǒng)的”腳本錯(cuò)誤處理,并獲取有關(guān)錯(cuò)誤的信息。