4.3.5 获取Server对象的路径信息
在对存储在Web网站上的文件进行操作时,需要获得文件的实际的物理路径,而不是使用虚拟路径或URL,尽管在其他网页中能用它们正常地定位文件。下一章中有一个例子,它使用FileSystemObject对Web站点的InetPub\WWWRoot文件夹中的文件进行读写。当创建自己的定制组件或者使用商业化的组件对文件系统进行访问时,经常需要为其提供一个文件的物理路径。
Server对象的MapPath方法
可以从Request.ServerVariables集合中提取HTTP报头变量,它们包含了当前文件的物理路径(在DOCUMENT_NAME和PATH_TRANSLATED报头中)。Server对象提供了一个方法MapPath,可以使用这个方法对我们能够提供一个有效的虚拟路径的任何文件提取相应的物理路径。可以在已经使用过的示例网页中看到使用MapPath方法,并可试验使用该方法。
如图4-24所示,在页面的底部的Miscellaneous Methods部分,有一个按钮执行Server.MapPath方法,并提供给它靠近该按钮的文本框中的值。在该网页的源代码中已经把这个值设置为“/iishelp/default.htm”,这个文件应该自动地安装在计算机上。也可以输入另一个网页的URL。
图4-24 使用Server.MapPath的屏幕
单击该按钮重新装载这个网页,执行该方法并在顶部显示结果,在下部显示原页面的其余部分,如图4-25所示:
图4-25 显示Server.MapPath的结果
(1) 示例网页代码的功能
处理这个过程的代码是与前面在相似的示例文件中已经使用过的代码十分相似。
在该页面顶部的ASP脚本区域中,对单击的按钮的名字进行检查。在这种情况下,该按钮的名字将是cmdMapPath,简单地把相匹配的文本框中的值txtMapPath传送给Server.MapPath方法,并显示得到的结果:
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和虚拟应用程序目录
注意,MapPath方法为/iishelp/default.htm文件获取的结果在Web服务器目录外,并在主winnt目录的help目录中。这清楚地证明了MapPath方法是非常有用的。
对于在缺省的Web网站目录中的文件,其URL的路径部分与物理路径通常是相同的。例如,一个文件存储在Web服务器上:
c:\InetPub\WWWRoot\yourfiles\thisfile.asp
如果安装时已经在缺省目录中安装了的Web根目录,则URL如下:
http://yoursite.com/yourfiles/thisfile.asp
然而,IIS Help文件安装在缺省Web网站目录外的一个虚拟目录中,所以用于对其进行访问的URL和物理路径之间没有直接的关联。只有通过使用Server.MapPath方法才能获取真实的物理路径。
4.3..6 使用Server对象格式化数据
当前面讨论演示SSI指令的网页的代码时,碰巧遇到了使用HTML的一个老问题。在一个HTML网页中如何显示HTML代码?如果“照现在的样子”使用,也就是在相应的位置上使用所有的HTML字符,会被浏览器当作HTML解释和执行。这样当下列内容在浏览器中显示时:
This is the syntax of a <TABLE> element:
将不会显示文本<TABLE>,因为浏览器将其作为一个数据表的一个开始标记,并照此来执行。为了避免这种情况,必须把在HTML中非法或无效的所有字符转换到等价的HTML字符实体(character entity)。多数常见的字符如表4-5所示:
表4-5 字符与等价的HTML实体的关系
字 符
等价的HTML实体
字 符
等价的HTML实体
<
<
>
>
&
&
“
"
©
©
®
®
所有的实体以&号开始并以分号结束,是在一些语言中表明一个实体的标准方法的一部分,这些语言是基于SGML(标准化常规标识语言)规则的,如HTML语言。
1. 数字的HTML实体等价字符串
注意最后一个例子,已经注册的商标®是一个以“#”字符为前缀的数字值,而不是相应含义的一个文本缩写(如copy对应版权符号©)。具有一个大于126的ANSI代码值的所有字符在HTML中被表示为十进制字符的ANSI代码,以&#为前缀,以分号为后缀。
事实上,需要留心的是使用数字实体等价字符串要优先于一些较少被支持文本实体字符串。一个例子是商标字符(™),该字符的实体等价字符串为“™”但不是所有浏览器(例如Navigator)都能识别这个字符串,这种情况下,将在网页中显示该实体字符串。相反,使用™在所有浏览器中都能很好地工作。
2. Server对象的HTMLEncode方法
把HTML转换为文本是进行有效显示需要的,否则HTML会被浏览器当成HTML来对待和执行,这意味着必须对无效的字符进行编码,使其成为等价的HTML实体字符串。为管理这种转换,Server对象提供了HTMLEncode方法。可以在本书提供的ASP Server Object示例网页中练习使用这个方法。
简单地把一些文本输入到HTMLEncode对应的文本框中并单击按钮。示例中提供了一些真实的HTML作为缺省的文本,如图4-26所示:
图4-26 使用HTMLEncode方法的屏幕
重新载入该页面时,在该页面的顶部显示结果。HTMLEncode方法把尖括号转换成了“<”和“>”,而且把双引号转换成为“";”,如图4-27所示:
图4-27 使用HTMLEncode方法1
(1) 示例网页代码的功能
关于得到的结果,有几个有趣的地方。
首先,在方法名字后面的括号中已经丢掉了<B>和</B>标记,相应增加了一个粗体文本部分。在网页中显示原有的值时,<B>和</B>被当成HTML提交了,所以<B>和</B>标记消失了,相关内容以粗体文本显示。
可以十分容易地避免这种情况。事实上,这就是设计HTMLEncode方法的原因。原示例代码如下:
…
Response.Write “Server.HTMLEncode (“ & QUOT & strValue & QUOT & “) returned”
…
现在所能做的就是把HTMLEncode方法应用于正在输出的值上:
…
strResult = Server.HTMLEncode(strValue)
Response.Write “Server.HTMLEncode (“ & QUOT & strResult & QUOT & “) returned”
现在输出了一个十分有用的结果,如图4-28所示:
图4-28 使用HTMLEncode方法的结果2
现在已经解决了不提交HTML而显示HTML的问题。但是如果要在HTML中显示HTMLEncode方法的结果,而又不提交和处理这些结果,又会发生什么情况?为了解决这个问题,要从HTMLEncode方法本身考虑:
This is <B>"bold"</B> text
上面的语句在HTML网页中得不到同样的显示结果,这是因为HTML字符实体将被浏览器处理和执行,并显示为实体所替代的字符。换句话说,得到的是:
This is <B>”bold”</B> text
我们没有看到实体。为了避免这种情况,可两次使用Server.HTMLEncode方法。这就把“&”号变换为“&”,这样就得到了所需的显示结果。示例网页的这个部分的代码是:
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控件的缺省值
从上面可以看出,如果在一个HTML网页中要显示HTML代码,而又不使之被作为HTML进行处理和执行,HTMLEncode方法是非常有用的。在大多数普通的ASP网页中不大可能会遇到这种情况,除非使用包含有HTML的数据库或其他数据源中的数据,而又需要作为文本进行显示。
但是HTMLEncode方法真正有用的地方是,通过设置VALUE属性预设页面中文本类型的HTML控件的值。作为例子,可看一下已经用于练习HTMLEncode方法的示例网页的源程序。创建HTMLEncode对应的文本框的HTML在HTML页中定义如下:
…
<INPUT TYPE=”TEXT” NAME=”txtHTMLEncode” SIZE=”35”
VALUE=”This is <B>"bold"</B> text”>
…
这是“手工编码”而不是使用Server.HTMLEncode方法。这里也只关心对双引号进行编码而不关心对尖括号的编码。为什么?这是因为如果没有这样做,该代码将被读为:
VALUE=”This is <B>”bold”</B> text”
而在这种情况中尖括号不会带来问题,未编码的双引号则会。在文本框中替换的实际值将是“This is <B>”,即它将在第二个双引号字符处被截断。所以,在创建预置控件值的页面时,应该考虑使用HTMLEncode方法,以避免这些值被截断:
<%
strValue = Request.Form(“txtSomeValue”)
%>
…
<INPUT TYPE=”TEXT” NAME=”txtSomeValue”
VALUE=”<% = ServerEncode(“strValue”) %>”>
…
当浏览器发送已经被HTML编码的一个控件的值给服务器时,自动进行反向译码。即服务器使用Request集合中原来格式的数据。
3. 格式化UTL的数据
还有另外一种情况,就是经常需要把一个文本字符串变换成能够在Web网页中使用的另外一种格式。现代Web服务器和操作系统都十分友好地支持包含空格字符的文件名,但是我们所使用的URL可能包含有空格字符,由于HTTP使用的URL语法不允许有空格字符(和几个其他字符),可能会出现麻烦。
另外一种更普遍的情况也会出现麻烦。当把这些值作为QueryString集合的成员传送给服务器时,将被追加到URL的末尾(在一个问号字符之后)。这种情况发生在<FORM>的METHOD属性被设置为“GET”(或者是省略了METHOD属性)的情况。换句话说,对于直接追加到URL上的值,都可能出现麻烦。这可能发生在<A>元素中:
<A HREF=http://myserver.com/mypage.asp?title=Instant Jscript>Instant Jscript</A>
一些浏览器(例如Internet Explorer)可以对此进行处理,因为它们在把HTTP请求发送到服务器之前,自动地执行必要的转换。然而,许多其他的浏览器不进行这种转换,并导致了URL通常在第一个空格或非法字符处被截断。这样在Navigator中,上面给出的链接要求的网页变为http://myserver.com/mypage.asp?title=Instant。在服务器上,title名字/值对的丢失部分会使代码失败。
考虑到HTTP协议定义的限制,必须从作为HTTP请求中的URL使用的字符串中删除非法的字符(非法字符是所有那些ANSI代码在126之上的字符和ANSI代码在126以下的某些字符)。
ANSI代码大于126的字符必须用百分号后跟十六进制形式的ANSI代码进行替换。这样,版权字符©变成%A9。ANSI代码在126之下在URL中不合法的字符,同样使用相应的替代字符串;如表4-6所示:
表4-6 字符与HTTP/URL代替物的关系
字 符
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对象的URLEncode方法
Server对象提供了可以用来把任意字符串转换成相应的合法HTTP URL的方法。可以利用示例网页对这个名为URLEncode的方法进行练习,如图4-29所示:
图4-29 使用URLEncode方法的屏幕
这里,输入的值作为URL是非法的,它包含了空格和ANSI代码大于126的字符。对这个值,使用URLEncode方法的结果是所有的空格被替换成一个加号,版权符号被替换为 %A9,如图4-30所示:
图4-30 使用URLEncode方法的结果
(1) 示例网页代码的功能
在示例网页中,处理这个功能的代码非常简单,仅仅检查是否单击了URLEncode方法对应的按钮,如果单击了,把对应的文本框中的值传递给Server.URLEncode方法并显示结果:
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) 对HTML元素和其他链接使用URLEncode
URLEncode方法更普遍地用于把<A>元素或其他链接的值写到ASP网页。例如,如果在查询字符串中建立了一系列的链接,这;些链接包含来自一个数据库的值,首先应该对这个字符串使用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的值包含标题“Active Server Pages©”,将得到由这个代码段创建的如下所示的HTML:
<A HREF=http://mysite.com/books.asp?title=Active+Server+Pages%A9>
Active Server Pages©</A>
注意,我们不仅仅使用Server.URLEncode方法来建立一个合法的URL字符串,而且还对链接的文本使用了Server.HTMLEncode方法,以确保把所有非法的字符转换为合适的HTML等价实体。
和HTMLEncode方法一样,不用反译码ASP网页中的URL编码值。IIS自动地实现URL编码字符串的转换,该字符串在HTTP请求中转换为它们原先格式,使得它们在内置对象中是可用的。
4.4 小结
在这一章中,通过在Web服务器上发生的处理过程,讨论了为Web网页提供动态内容所涉及的一些问题。这些问题的一部分不是直接地与ASP本身相关,但对这些问题的理解,将有助于理解基本的处理工作是如何进行的。
本章介绍了IIS如何支持传统的服务器端包含指令,有一些指令可能仍然是有用的。特别是,#exec指令对执行系统命令以及集成原有的应用程序都是有用的。同时也讨论了一条特别的服务器端包含指令——#include语句,了解了在ASP网页内部使用这条命令的相关问题。
然而,ASP Server对象占了本章的大部分。它提供了在ASP网页内管理服务器端处理过程的方法。在Web服务器和ASP的正确的环境中,它可用来创建其他对象、应用程序或组件的实例。它同时也提供了一系列的方法,这些方法允许执行其他的网页或资源,以及以正确方式格式化信息,以便在ASP脚本和网页中使用。 Server对象也带来了一个新的ASP内置对象:ASPError对象,它为脚本提供较好的错误处理方法。现在可以提供“正统的”脚本错误处理,并获取有关错误的信息。