14-2 讀A僂

Request 物件內含 Request.ServerVariables 集合,此集合包含了伺服器環境變數的值,這些環境變數涵蓋了用戶端和伺服器端的各種資訊。

例如,若要得知用戶端及伺服器端的 IP,可用下列方式取得:

範例如下:

Example(requestIp01.asp):

上述範例的原始檔如下:

原始檔(requestIp01.asp):(灰色區域按兩下即可拷貝)
<%@language=jscript%>
<%title="使用 Request.ServerVariables 來抓取 IP"%>
<!--#include file="head.inc"-->
<hr>

<li>HTTP request 來源 IP: Request.ServerVariables("REMOTE_ADDR") = <font color=red><%=Request.ServerVariables("REMOTE_ADDR")%></font>
<li>HTTP request 伺服器 IP: Request.ServerVariables("LOCAL_ADDR") = <font color=red><%=Request.ServerVariables("LOCAL_ADDR")%></font>
<li>HTTP request 代理伺服器: Request.ServerVariables("HTTP_VIA") = <font color=red><%=Request.ServerVariables("HTTP_VIA")%></font>
<li>HTTP request 原始來源 IP: Request.ServerVariables("HTTP_X_FORWARDED_FOR") = <font color=red><%=Request.ServerVariables("HTTP_X_FORWARDED_FOR")%></font>

<hr>
<!--#include file="foot.inc"-->

如果你得到的客戶端 IP 並不等於你的電腦的 IP,哪麼可能是你的瀏覽器被設定成經由代理伺服器(Proxy Server)來取得網頁,因此 Request.ServerVariables("REMOTE_ADDR") 就變成代理伺服器的 IP 了。在這種情況下,我們可由 Request.ServerVariables("HTTP_VIA") 來顯示所用到的代理伺服器,並由 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 取得真正客戶端的 IP。當然,如果你的瀏覽器並沒有設定使用代理伺服器,那麼經由 Request 物件所抓到的變數 Request.ServerVariables("HTTP_VIA") 和 Request.ServerVariables("HTTP_X_FORWARDED_FOR") 都只是空字串而已。

Hint
你可以設定或取消代理伺服器後,再看看上述範例的結果是否有變化。

一個簡單的應用,就是檢查來源 IP,而決定是否提供網頁瀏覽。例如,如果我們的線上教材只開放給清大的同學看,那我們就可以直接檢查原始來源 IP 是否為 140.114.xxx.xxx,若不是,則不傳送網頁,範例如下:

Example(requestIp02.asp):

上述範例的原始檔如下:

原始檔(requestIp02.asp):(灰色區域按兩下即可拷貝)
<%@language=jscript%>
<%title="限制能夠瀏覽此網頁的 IP"%>
<!--#include file="head.inc"-->
<hr>

<%
ip=Request.ServerVariables("REMOTE_ADDR")+"";
proxy=Request.ServerVariables("HTTP_VIA")+"";
if (proxy!="undefined")		// 若有使用代理伺服器,則抓取原始用戶端 IP
	ip=Request.ServerVariables("HTTP_X_FORWARDED_FOR")+"";
Response.write("原始用戶端 IP = " + ip + "<br>");
Response.write("Proxy = " + proxy + "<br>");
domain="140.112.";
if (ip.indexOf(domain)!=0){
	Response.write("This page is not allowed!");
	Response.end;	// 停止網頁傳送!
}
%>

這是台大 IP 能夠看到的正常網頁!

<hr>
<!--#include file="foot.inc"-->

Hint
在使用 ASP 物件時,若要將物件內的字串設定到另一個字串變數時,我們通常使用「ip=Request.ServerVariables("REMOTE_ADDR")+""」的方式,如此強制轉型,才能避免因為 Request.ServerVariables("REMOTE_ADDR") 可能不是一個字串物件所帶來的困擾。

與伺服器相關的資訊,可以列出如下:

範例如下:

Example(requestServer01.asp):

上述範例的原始檔如下:

原始檔(requestServer01.asp):(灰色區域按兩下即可拷貝)
<%@language=jscript%>
<%title="使用 Request.ServerVariables 來列出與伺服器相關的資訊"%>
<!--#include file="head.inc"-->
<hr>

<ul>
<li>伺服器網域名稱:Request.ServerVariables("SERVER_NAME") = <font color=red><%=Request.ServerVariables("SERVER_NAME")%></font>
<li>伺服器埠號:Request.ServerVariables("SERVER_PORT") = <font color=red><%=Request.ServerVariables("SERVER_PORT")%></font>
<li>伺服器協定:Request.ServerVariables("SERVER_PROTOCOL") = <font color=red><%=Request.ServerVariables("SERVER_PROTOCOL")%></font>
<li>網頁伺服器軟體名稱:Request.ServerVariables("SERVER_SOFTWARE") = <font color=red><%=Request.ServerVariables("SERVER_SOFTWARE")%></font>
<li>伺服器加密:Request.ServerVariables("SERVER_PORT_SECURE") = <font color=red><%=Request.ServerVariables("SERVER_PORT_SECURE")%></font>
</ul>

<hr>
<!--#include file="foot.inc"-->

與網頁路徑相關的資訊,可以列出如下:

範例如下:

Example(requestPath01.asp):

上述範例的原始檔如下:

原始檔(requestPath01.asp):(灰色區域按兩下即可拷貝)
<%@language=jscript%>
<%title="使用 Request.ServerVariables 來列出與網頁路徑相關的資訊"%>
<!--#include file="head.inc"-->
<hr>

<ul>
<li>伺服器根目錄的實體硬碟路徑:Request.ServerVariables("APPL_PHYSICAL_PATH") = <font color=red><%=Request.ServerVariables("APPL_PHYSICAL_PATH")%></font>
<li>網頁在實體硬碟的路徑:Request.ServerVariables("PATH_TRANSLATED") = <font color=red><%=Request.ServerVariables("PATH_TRANSLATED")%></font>
<li>網頁相對應於伺服器根目錄的路徑:Request.ServerVariables("PATH_INFO") = <font color=red><%=Request.ServerVariables("PATH_INFO")%></font>
<li>網頁相對應於伺服器根目錄的路徑:Request.ServerVariables("SCRIPT_NAME") = <font color=red><%=Request.ServerVariables("SCRIPT_NAME")%></font>
<li>網頁相對應於伺服器根目錄的路徑:Request.ServerVariables("URL") = <font color=red><%=Request.ServerVariables("URL")%></font>
</ul>

<hr>
<!--#include file="foot.inc"-->

在上述範例中,Request.ServerVariables("PATH_INFO")、Request.ServerVariables("SCRIPT_NAME") 和 Request.ServerVariables("URL") 都會回傳一樣的結果。

其他有用的資訊也都可以由 Request.ServerVariables 取得,例如:

範例如下:

Example(requestHttpReferer01.asp):

上述範例的原始檔如下:

原始檔(requestHttpReferer01.asp):(灰色區域按兩下即可拷貝)
<%@language=jscript%>
<%title="使用 Request.ServerVariables 來抓取「連結至目前網頁的前一個網頁」"%>
<!--#include file="head.inc"-->
<hr>

<ul>
<li>連結至目前網頁的前一個網頁:Request.ServerVariables("HTTP_REFERER") = <font color=red><%=Request.ServerVariables("HTTP_REFERER")%></font>
<li>用戶端所用的瀏覽器:Request.ServerVariables("HTTP_USER_AGENT") = <font color=red><%=Request.ServerVariables("HTTP_USER_AGENT")%></font>
<li>用戶端登錄至網頁的帳號:Request.ServerVariables("LOGON_USER") = <font color=red><%=Request.ServerVariables("LOGON_USER")%></font>
</ul>

<hr>
<!--#include file="foot.inc"-->

使用 Request.ServerVariables("HTTP_REFERER"),你可以得知下列事項:

若欲將 Request.ServerVariables 所有相關變數一次印出,可見下列範例:

Example(request/serverVariables.asp):

上述範例的原始檔如下:

原始檔(request/serverVariables.asp):(灰色區域按兩下即可拷貝)
<%@ language="jscript" %>
<% title="列出 Request.ServerVariables" %>
<!--#include file="../head.inc"-->
<hr>

<!--#include file="../listdict.inc"-->
<% listdict(Request.ServerVariables, "Request.ServerVariables"); %>

<hr>
<!--#include file="../foot.inc"-->

此原始檔包含了 listdict.inc,其原始檔案如下:

原始檔(listdict.inc):(灰色區域按兩下即可拷貝)
<script runat=server language=jscript>
function listdict(dict, dictname){
	Response.Write("<table border=1 align=center>\n");
	Response.Write("<tr><th colspan=2 bgcolor=cyan>" + dictname + "\n");
	Response.Write("<tr><th>Names<th>Values\n");
	var Enum=new Enumerator(dict);
	for (Enum.moveFirst(); !Enum.atEnd(); Enum.moveNext()){
		Response.Write("<tr><td>");
		Response.Write(dictname+"(\""+Enum.item()+"\")\n");
		Response.Write("<td>");
		Response.Write(dict(Enum.item())+"&nbsp;");
	}
	Response.write("</table>\n");
}
</script>

<script runat=server language=vbscript>
function listdict(dict, dictname)
	dim key
	response.write("<table border=1 align=center>" & vbcrlf)
	response.write("<tr><th colspan=2 bgcolor=cyan>" & dictname & vbcrlf)
	response.write("<tr><th>Names<th>Values" & vbcrlf)
	For Each key in dict
		response.write("<tr>" & newline)
		response.write("<td>" & dictname & "(""" & key & """)</td>")
		response.write("<td>&nbsp;" & dict(key) & "</td>")
		response.write("</tr>" & vbcrlf)
	next
	response.write("</table>" & vbcrlf)
end function
</script>

listdict.inc 包含兩個函數,分別用於對付 JScript 和 VBScript,可列印出任何 Dictionary 變數,例如上述範例的 Request.ServerVariables。在 JScript 的 listdict() 函數中,我們用到了 Enumerator 的物件,此物件是類似於 VBScript 的 Dictionary 變數,可用字串來索引另一個字串。

若要知道 Request.ServerVariables 所包含變數的意義,可以直接查看下列網頁:

http://www.devguru.com/index.asp?page=/technologies/asp/quickref/request_servervariables.html
瞭解並善用這些伺服器環境變數,可使妳的 Web 程式設計事半功倍。

上述印所有 Request.ServerVariables 的方法,是用 JScript 來達成,我們也可以使用 VBScript 來達到相同功能,請見範例程式碼「example/request/serverVariables_vbs.asp」,此程式碼也包含了相同的 listdict.inc,以便列出所有的伺服器變數。


JScript 程式設計與應用:用於伺服器端的 ASP 環境