發新話題

Asp深度揭密

Asp深度揭密

一、Asp基本知識

1.Asp是Active Server Pages的簡稱,是解釋型的腳本語言環境;
2.Asp的運行需要Windows操作系統,9x下需要安裝PWS;而NT/2000/XP則需要安裝Internet Information Server(簡稱IIS);
3.Asp和JSP的腳本標籤是「<%%>」,PHP的則可以設定為多種;
4.Asp的註釋符號是「'」;
5.使用附加組件,可以擴展Asp的功能。

例子:

HelloWorld_1.asp
<%="Hello,world"%>

效果:
Hello,world


HelloWorld_2.asp
<%
for i=1 to 10
response.write "Hello,world"
next
%>

效果:
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world
Hello,world

注意:Asp不區分大小寫;變量無需定義也可使用,轉換方便;語法檢查很鬆。


二、Asp內置對象的使用:

可以使用下面的任何ASP內置對象,而不必在ASP腳本中特別聲明。

1. Request:

定義:可用來訪問從瀏覽器發送到服務器的請求信息,可用此對像讀取已輸入HTML表單的信息。

集:
Cookies:含有瀏覽器cookies的值
Form:含有HTML表單域中的值
QueryString:含有查詢字符串的值
ServerVariables:含有頭和環境變量中的值

例子:

request_url.asp
<%
'獲取用戶輸入,並存入變量
user_id=request.querystring("user_id")
user_name=request.querystring("user_name")

'判斷用戶輸入是否正確
if user_id="" then
response.write "User_id is null,please check it"
response.end
end if
if user_name="" then
response.write "User_name is null,please check it"
response.end
end if

'打印變量
response.write user_id&"<br>"
response.write user_name
%>

效果:
當訪問訪客無法瀏覽此圖片或連結,請先 註冊登入會員 時:
User_id is null,please check it
當訪問訪客無法瀏覽此圖片或連結,請先 註冊登入會員 時:
my_id
j

思考:變量是如何在URL中傳遞和被Asp頁面獲取的?


request_form.htm
<style type="text/css">
<!--
.input {background-color: #FFFFFF; border-bottom: black 1px solid;border-left: black 1px solid; border-right: black 1px solid;border-top: black 1px solid; color: #000000;font-family: Georgia; font-size: 9pt;color: midnightblue;}
a:link {color: #1B629C; text-decoration: none}
a:hover {color: #FF6600; text-decoration: underline}
a:visited {text-decoration: none}
-->
</style>

<center>
<form name="course" action="request_form.asp" method="post">
User_id:<input type="text" name="user_id" maxlength="20" class="input"><br><br>
User_name:<input type="text" name="user_name" maxlength="30" class="input">
</form>
<br><br>
<a href="javascript:document.course.submit();"> 提 交 </a>
</center>

request_form.asp
<%
'獲取用戶輸入,並存入變量
user_id=request.form("user_id")
user_name=request.form("user_name")

'判斷用戶輸入是否正確
if user_id="" then
response.write "User_id is null,please check it"
response.end
end if
if user_name="" then
response.write "User_name is null,please check it"
response.end
end if

'打印變量
response.write user_id&"<br>"
response.write user_name
%>

注意:form的action的指向,request_form.asp和request_url.asp在源代碼上的區別?

2. Response:

定義:用來向瀏覽器回發信息,可用此對像從腳本向瀏覽器發送輸出。

集:
Cookies:在瀏覽器中加入一個cookie

方法:
End:結束腳本的處理
Redirect:將瀏覽器引導至新頁面
Write:向瀏覽器發送一個字符串

屬性:
Buffer:緩存一個ASP
CacheControl:由代理服務器控制緩存
ContentType: 規定響應的內容類型
Expires:瀏覽器用相對時間控制緩存
ExpiresAbsolute:瀏覽器用絕對時間控制緩存

例子:

response_redirect.asp
<%
'去google看看吧
response.redirect "http://www2.google.com"
response.end
%>


response_cookies.asp
<%
'設置和讀取cookies
response.cookies("time_now")=now()
response.write request.cookies("time_now")
%>

效果:
當訪問訪客無法瀏覽此圖片或連結,請先 註冊登入會員 時:
2002-9-1 16:20:40


response_buffer.asp
<%'response.buffer=true%>
<a href="a">a</a>
<%response.redirect "request_form.htm"%>

效果:
.當關閉IIS的緩衝功能,訪問該頁面時出錯
a
答覆對像 錯誤 'ASP 0156 : 80004005'
頭錯
/course/response_buffer.asp,行3
HTTP 頭已經寫入到 客戶瀏覽器。任何 HTTP 頭的修改必須在寫入頁內容之前。
.當關閉IIS的緩衝功能,去掉文件第一行的註釋,則頁面重定向成功
.當打開IIS的緩衝功能,無論是否去掉文件第一行的註釋,頁面重定向都成功

3. Server

定義:可在服務器上使用不同實體函數,如在時間到達前控制腳本執行的時間。還可用來創建其他對象。

方法:
CreateObject:創建一個對像實例
HTMLEncode:將字符串轉化為使用特別的HTML字符
MapPath:把虛擬路徑轉化成物理路徑
URLEncode:把字符串轉化成URL編碼的
ScriptTimeout:在終止前,一個腳本允許運行的秒數

例子:

server_htmlencode.asp
<%
'html encode
response.write server.htmlencode("a""time_now")
%>

效果:
a"time_now
查看源文件時顯示為:a"time_now

思考:為什麼不是a""time_now這種效果?源文件是怎麼了?


server_mappath.asp
<%
'mappath
response.write server.mappath("server_mappath.asp")
%>

效果:
G:asp_wwwtestcourseserver_mappath.asp

思考:如何獲取站點根目錄的實際路徑?如何獲取某個目錄的實際路徑?


server_urlencode.asp
<%
'url encode
response.write server.urlencode("atime_now")
%>

效果:
a%5Ctime%5Fnow

4. Application

定義:用來存儲、讀取用戶共享的應用程序信息,如可以用此對像在網站的用戶間傳送信息,當服務器重啟後信息丟失。

方法:
Lock:防止其它用戶訪問Application集
Unlock:使其它用戶可以訪問Application集

事件:
OnEnd:由終止網絡服務器、改變Global.asa文件觸發
OnStart:由應用程序中對網頁的第一次申請觸發

例子:

application_counter.asp
<%
'一個使用Application製作的簡單計數器
Application.lock
Application("clicks")=Application("clicks")+1
Application.unlock

response.write "您是本站第 "&Application("clicks")&" 位訪客!"
response.write "<br><br>您來自 "&request.servervariables("remote_addr")
%>

效果:
您是本站第 1 位訪客!

您來自 10.1.43.238

思考:本例中lock和unlock有何作用?

5. Session

定義:存儲、讀取特定用戶對話信息,如可存儲用戶對網站的訪問信息,當服務器重啟後信息丟失。

方法:
Abandon:處理完當前頁面後,結束一個用戶會話

屬性:
Timeout:用戶會話持續時間(分鐘數)

事件:
OnEnd:在Session Timeout時間以外,用戶不再申請頁面觸發該事件
OnStart:由用戶對網頁的第一次申請時觸發

例子:

session_counter.asp
<%
'一個使用Session製作的簡單計數器
session("clicks")=session("clicks")+1

response.write "您是本站第 "&session("clicks")&" 位訪客!"
response.write "<br><br>您來自 "&request.servervariables("remote_addr")
%>

效果:
您是本站第 1 位訪客!

您來自 10.1.43.238

思考:既然session和application都能做到計數,那它們之間有什麼區別?如果要做到滿100重新開始計數如何實現?

TOP

三、使用Asp操作數據庫:

1.通過ODBC或者OLE方式連接的區別?

現在有兩種連接數據庫的方法。一方面,可以用ODBC產生一個連接,這種連接與任何有ODBC驅動器的數據庫(即基本上是市場上所有的數據庫)兼容;另一方面,可以用原始OLE DB提供商產生一個連接。

該用哪個提供商?盡可能用原始OLE DB提供商,因為它提供了對數據更有效的訪問。Microsoft正逐步用OLE DB取代ODBC標準,應該僅僅在沒有原始OLE DB提供商時使用ODBC。

.用ODBC方式連接SQL Server:
.配置ODBC
.連接代碼:
conn_odbc.asp
<%
Set Conn = Server.CreateObject("ADODB.Connection")
'Conn.Open "DSN=course_dsn;UID=course_userWD=course_password;DATABASE=course"
Conn.Open "course_dsn","course_user","course_password"
%>
注意:在配置MyDSN時若指定默認數據庫為course則上述代碼作用想同,否則第二行的連接方式更有靈活性,可以指定連接某個數據庫(當然,前提是course_user對這個數據庫有操作權限)。

.用OLE方式連接SQL Server:
conn_ole.asp
<%
Set Conn = Server.CreateObject("ADODB.Connection")
Conn.Open "ROVIDER=SQLOLEDB;DATA SOURCE=10.1.43.238,2433; UID=course_userWD=course_password;DATABASE=course"
%>

2.操作數據庫:Connection和Recordset

聯合使用connection和recordset操作數據庫,或者只使用connection操作數據庫。

例子:

.聯合使用connection和recordset操作數據庫

use_db_1.asp
<%
Set conn=Server.CreateObject("ADODB.Connection") '創建連接數據庫的對象
conn.Open "course_dsn","course_user","course_password" '使用該對像連接數據庫
Set rs=Server.CreateObject("ADODB.RecordSet") '創建記錄集對像
rs.Open "select * from user_info",conn,1,1 '使用記錄集對像打開數據庫
if rs.recordcount>0 then '如果有記錄
response.write "User_id User_name<br>"
for i=1 to rs.recordcount '循環讀取所有紀錄
response.write rs("id")&" "&rs("user_name")&"<br>"
'向瀏覽器輸出紀錄的字段
rs.movenext '指針下移一行
if rs.eof then exit for '如果到達記錄集底部則退出循環
next
end if
%>

效果:
User_id User_name
1 ahyi
3 test


.只使用connection操作數據庫:

use_db_2.asp
<%
Set conn=Server.CreateObject("ADODB.Connection") '創建連接數據庫的對象
conn.Open "course_dsn","course_user","course_password" '使用該對像連接數據庫
conn.execute "delete from user_info"
%>

效果:
user_info表中所有數據被刪除

思考:兩種方式有和區別?各應用於什麼場合?

3.如何使用事務處理、存儲過程和視圖?

.使用存儲過程

.定義好存儲過程

CREATE PROCEDURE [output_1]
@sid int output
AS
set @sid=2

CREATE PROCEDURE [return_1]
(@user_name varchar(40),@password varchar(20))
AS
if exists(select id from user_info where user_name=@user_name and password=@password)
return 1
else
return 0

CREATE PROCEDURE [user_info_1]
(@user_name varchar(40),@password varchar(20))
AS
select id from user_info where user_name=@user_name and password=@password

CREATE PROCEDURE [user_info_2]
(@user_name varchar(40),@password varchar(20))
AS
SET XACT_ABORT ON
BEGIN TRANSACTION
delete from user_info where user_name=@user_name and password=@password
COMMIT TRANSACTION
SET XACT_ABORT OFF

CREATE PROCEDURE [user_info_3] AS
select * from user_info

.在Asp中調用

use_proc.asp
<!-- #include virtual="/adovbs.inc" -->
<%
Set conn=Server.CreateObject("ADODB.Connection")
conn.Open "course_dsn","course_user","course_password"

'使用recordset調用帶兩個輸入參數和返回紀錄集的存儲過程
'CREATE PROCEDURE [user_info_1]
'(@user_name varchar(40),@password varchar(20))
'AS
'select id from user_info where user_name=@user_name and password=@password
response.write "普通的調用方法:<br>"
set rs=server.createobject("adodb.recordset")
sql="user_info_1 '"&request.querystring("user_name")&"','"&request.querystring("password")&"'"
rs.open sql,conn,1,1
response.write rs("id")&"<br>"
rs.close

'使用recordset調用無輸入參數,返回紀錄集的存儲過程,可以使用recordcount等屬性
'CREATE PROCEDURE [user_info_3] AS
'select * from user_info
response.write "<br>返回紀錄集,可以使用recordcount等屬性:"
sql="exec user_info_3"
rs.open sql,conn,1,1
for i=1 to rs.recordcount
response.write "<br>"&rs("user_name")
rs.movenext
next
rs.close
set rs=nothing

'使用command調用帶輸出參數的存儲過程
'CREATE PROCEDURE [output_1]
'@sid int output
'AS
'set @sid=2
response.write "<br><br>調用帶輸出參數的存儲過程:<br>"
set cmd=server.createobject("adodb.command")
cmd.activeconnection=conn
cmd.commandtext = "output_1"
cmd.parameters.append cmd.createparameter("@sid",adinteger,adparamoutput)
cmd("@sid")=10
cmd.execute()
bbb=cmd("@sid")
response.write bbb&"<br>"
set cmd=nothing

'使用command調用帶兩個輸入參數和返回值的存儲過程
'CREATE PROCEDURE [return_1]
'(@user_name varchar(40))
'AS
'if exists(select id from user_info where user_name=@user_name)
'return 1
'else
'return 0
response.write "<br>調用帶兩個輸入參數和返回值的存儲過程:<br>"
set cmd=server.createobject("adodb.command")
cmd.activeconnection=conn
cmd.commandtype = adcmdstoredproc
cmd.commandtext = "return_1"
cmd.parameters.append cmd.createparameter("@return_value",adinteger,adparamreturnvalue)
cmd.parameters.append cmd.createparameter("@user_name",advarchar,adparaminput,40)
cmd.parameters.append cmd.createparameter("@password",advarchar,adparaminput,20)
cmd("@user_name")="tuth"
cmd("@password")="yyuyu"
cmd.execute()
rrr=cmd("@return_value")
response.write rrr
set cmd=nothing

conn.close
set conn=nothing
%>

效果:
訪問訪客無法瀏覽此圖片或連結,請先 註冊登入會員 時,出現如下

普通的調用方法:
12

返回紀錄集,可以使用recordcount等屬性:
ahyi
tet
tuth

調用帶輸出參數的存儲過程:
2

調用帶兩個輸入參數和返回值的存儲過程:
1

注意:若存儲過程無參數,則調用的sql語句直接為存儲過程名,一個參數為「存儲過程名 參數」,若是多個參數,則「存儲過程名 參數1,參數2,……,參數n」;如果在sql語句中加入exec,則在返回的記錄集中可以使用recordcount等屬性;如果想獲得存儲過程的返回值或輸出參數,可以使用command對象。

.使用事務處理

.Asp內嵌的事務支持

例子:
use_transaction_1.asp
<%
'Asp中使用事務
Set conn=Server.CreateObject("ADODB.Connection")
conn.Open "course_dsn","course_user","course_password"
conn.begintrans '開始事務

sql="delete from user_info"
set rs=server.createobject("adodb.recordset")
rs.open sql,conn,3,3
if conn.errors.count>0 then '有錯誤發生
conn.rollbacktrans '回滾
set rs=nothing
conn.close
set conn=nothing
response.write "交易失敗,回滾至修改前的狀態!"
response.end
else
conn.committrans '提交事務
set rs=nothing
conn.close
set conn=nothing
response.write "交易成功!"
response.end
end if
%>

.數據庫級的事務

i.創建存儲過程

CREATE PROCEDURE [user_info_2]
(@user_name varchar(40),@password varchar(20))
AS
SET XACT_ABORT ON
BEGIN TRANSACTION
delete from user_info where user_name=@user_name and password=@password
COMMIT TRANSACTION
SET XACT_ABORT OFF

ii.在Asp中調用

use_transaction_2.asp
<%
Set conn=Server.CreateObject("ADODB.Connection")
conn.Open "course_dsn","course_user","course_password"

sql="user_info_2 '"&request.querystring("user_name")&"','"&request.querystring("password")&"'"

set rs=server.createobject("adodb.recordset")
rs.open sql,conn,1,1
set rs=nothing
conn.close
set conn=nothing
%>

討論:兩種方式的優劣?

.使用視圖
在數據庫中定義好視圖之後,在Asp中如同使用一個表一樣來使用視圖

4.一個數據庫分頁的例子

db_page.asp
<%
on error resume next
Set conn=Server.CreateObject("ADODB.Connection") '創建連接數據庫的對象
conn.Open "course_dsn","course_user","course_password" '使用該對像連接數據庫
set rs=server.createObject("adodb.recordset")
sql="select * from user_info order by id desc"
rs.open sql,conn,1,1

if rs.recordcount>0 then '如果有記錄
rs.pagesize=2 '每頁最多顯示2條紀錄
'從URL獲取當前要顯示的頁
page=cint(request("page"))
'頁面參數異常處理
if page="" then page=1
if page<1 then page=1
if page>= rs.pagecount then page=rs.pagecount
rs.absolutepage=page '當前頁為page參數指定的頁
for i=1 to rs.pagesize '根據pagesize參數的大小循環顯示當前頁中的紀錄
response.write "User_id:"&rs("id")&"<br>"
response.write "User_name:"&rs("user_name")&"<br><br>"
rs.movenext '紀錄指針下移
if rs.eof then exit for '如果到達紀錄集底部則退出循環
next
end if

'顯示翻頁按鈕
if page>1 then
response.write "<a href="&request.servervariables("document_name")&"?page=1>第一頁</a> "
response.write "<a href="&request.servervariables("document_name")&"?page="&(page-1)&">上一頁</a> "
end if
if page<>rs.pagecount then
response.write "<a href="&request.servervariables("document_name")&"?page="&(page+1)&">下一頁</a> "
response.write "<a href="&request.servervariables("document_name")&"?page="&rs.pagecount&">最後一頁</a> "
end if
response.write"頁碼:"&page&"/"&rs.pagecount

'關閉對象,釋放內存
rs.close
set rs=nothing
conn.close
set conn=nothing
%>

思考:分頁過程中使用了哪些額外的屬性?

TOP

四、Asp組件的開發與使用:

1. 組件的特點?

l 優點:
n 調用方便,節省代碼
n 安全性高
n 支持事務處理,多組件聯合
n 運行速度快
n 升級、修改組件不需修改頁面,因此擴展性好
l 缺點:
n 開發及調試困難

2. 如何使用VB開發?

.打開VB>>New Project>>ActiveX DLL

.修改項目名稱為course


.修改類模塊的名字為conn_db


.Project>> References,引用COM+ Service Type Library和Microsoft Active Server Pages Object Library。

.修改類代碼如下:

'建立數據庫連接並輸出數據庫字段
Dim Response As Response
Dim Request As Request
Dim Server As Server
Dim Application As Application
Dim Session As Session

Private Sub Class_Initialize()
Dim objContext As ObjectContext
Set objContext = GetObjectContext()
Set Response = objContext("Response")
Set Request = objContext("Request")
Set Server = objContext("Server")
Set Application = objContext("Application")
Set Session = objContext("Session")
End Sub

Sub conn_db()
Set conn = CreateObject("adodb.connection")
conn.open "course_dsn", "course_user", "course_password"
Set rs = CreateObject("adodb.recordset")
rs.open "select * from user_info", conn, 1, 1

If rs.recordcount > 0 Then
For i = 1 To rs.recordcount
Response.write "<br>" & rs("user_name") & "<br>"
If rs.EOF Then Exit For
rs.movenext
Next
End If
rs.Close
Set rs = Nothing
conn.Close
Set conn = Nothing
End Sub

.添加一新類cutstr

.修改類代碼如下:

'截取字符串
Function cutstr(str, length)
If Len(str) > length Then
cutstr = Left(str, length) & "..."
Else
cutstr = str
End If
End Function

.File>>Save

.File>>make course.dll

3. 註冊組件:MTS和regsvr32.exe

有兩種方式註冊組件:MTS和使用regsvr32.exe。MTS是值得推薦的,因為它具有下列優點:
n 動態卸載平衡,提高組件和基於組件的應用程序的升級性。
n 包含公佈和提交事件和隊列組件的能力,使得更容易與多個組件聯合。

要想使組件具有MTS的特性,必須對組件做少許改動。在NT和98下開發時,必須在項目中引用Microsoft Transaction Server Type Library,在Windows 2000下開發,必須引用COM+ Service Type Library。

.regsvr32註冊:

regsvr32.exe是system32下面的一個可執行文件,它將組件信息讀入註冊表,以便Asp調用。
使用命令行進入組件dll文件所在的目錄,執行「regsvr32 dll_file_name」即可。


運行regedit,在HKEY_CLASSES_ROOT下就會找到course.conn_db項和course.cutstr項,表明組件註冊成功。


.使用MTS註冊:

.開始>>程序>>管理工具>>組件服務

.展開目錄至如下狀態:


.按照嚮導,下一步,直到如下對話框,點擊「創建一個空的應用程序」:


.在接下來的對話框中,為應用程序起名為「course」,其他默認,直至完成

.展開course應用程序,右鍵,新建一個組件


.按照提示,繼續,出現如下對話框時,選擇「導入已被註冊的組件」


.選擇我們開發的組件,下一步,直至完成


.這時候,可以發現course應用程序下已經多了兩個組件:


4. 在Asp中調用組件

asp_use_com.asp
<%
'asp調用com組件
set cutstr_obj=server.createobject("course.cutstr")
response.write cutstr_obj.cutstr("abcdefghijk",3)&"<br>"
set cutstr_obj=nothing

set conn_obj=server.createobject("course.conn_db")
conn_obj.conn_db()
set conn_obj=nothing
%>

效果:
abc...

ahyi

tuth

說明調用成功。

5. 卸載組件

.使用regsvr32註冊的組件,使用-u開關卸載:


注意:先進入組件dll所在的目錄,然後使用「regsvr32 –u dll_file_name」卸載;卸載後重啟IIS即可。

.使用MTS註冊的組件,先在「組件服務」中刪除對應的應用程序,然後再執行步驟  以徹底卸載組件。


6. Dll組件存放位置和權限設定

.我們只需要把編譯生成的Dll文件拷貝出來即可,其他的文件不用做處理
.要把Dll放到Web站點之外,如system32目錄裡,防止被下載
.Dll的文件權設置為System讀取,Internet用戶遍歷文件夾/運行文件
.Dll在IIS中去掉所有的權限,如讀取,腳本自願訪問等
經過上述處理,可以確保Dll文件的安全。

7. 其他

如何在組件中使用Asp的對象以方便的將Asp代碼移植為COM組件?


五、IIS最優化配置

1.Web站點選項卡:IP、端口、虛擬主機、連接、日誌
2.ISAPI篩選器:加入PHP和JSP支持
3.主目錄配置選項卡:I IS權限設定(結合文件權)、執行許可、應用程序保護、映射、緩衝、父路徑、出錯信息
4.其他選項卡:自定義錯誤、Http頭、目錄安全性、文檔
5.文件壓縮帶來的好處和壞處


六、其他

1. 發送郵件(JMail;Ms smtp)

使用Microsoft Smtp發送電子郵件
.安裝Microsoft SMTP Service
.設置Microsoft SMTP Service
.代碼部分:
mail_smtp.asp
<%
sub sendmail(fromwho,towho,subject,body)
dim mymail
set mymail = server.createobject("cdonts.newmail")
mymail.from = fromwho
mymail.to = towho
mymail.subject = subject
mymail.body = body
mymail.send
set mymail = nothing
end sub
%>

該子程序接受4個與下列各條對應的參數。
l 郵件發送者的email地址
l 郵件接收者的email地址
l 郵件主題
l 郵件內容

使用方法:
<%
fromWho=…
toWho=…
Subject=…
Body=…

IF toWho <> "" THEN
sendMail fromWho, toWho, Subject, Body
END IF
%>

使用Jmail發送Email
略,有興趣可以和我探討,Jmail這個軟件我也有。

2. 解壓Zip文件(Wscript.Shell和Winzip command line;Java組件)

.安裝Winzip 8.1以上
.安裝Winzip command line
.將工作目錄的文件權設置為Internet用戶可以讀取、寫入和修改
.代碼部分:
unzip_a_zipfile.asp
<%
'用shell對像啟動程序
'zip_path是具體zip文件的路徑,如c:test.zip
'path是存放解壓後文件的路徑
'ond是命令行參數
set wshshell = server.createobject("wscript.shell")
issuccess = wshshell.run ("wzunzip -ond "&zip_path&" "&path,1,true)

'刪除zip文件
set myfileobject=server.createobject("scripting.filesystemobject")
myfileobject.deletefile zip_path

'判斷是否成功以繼續操作
if issuccess = 0 then
'成功
...
else
'失敗
...
end if
%>

3. 操作XML文件

本次交流時間有限,有時間再做詳細探討

4.文件上傳

.安裝文件上傳組件Asp fileup(支持多文件上傳,文件類型及大小判斷,文件上傳後改名等)
.重起IIS以使上傳組件生效
.設置上傳目錄的文件權為Internet用戶可以讀取、寫入和修改
.代碼部分
upload_file.htm
<style type="text/css">
<!--
.input {background-color: #FFFFFF; border-bottom: black 1px solid;border-left: black 1px solid; border-right: black 1px solid;border-top: black 1px solid; color: #000000;font-family: Georgia; font-size: 9pt;color: midnightblue;}
a:link {color: #1B629C; text-decoration: none}
a:hover {color: #FF6600; text-decoration: underline}
a:visited {text-decoration: none}
-->
</style>

<center>
<form enctype="multipart/form-data" method="post" action="upload_file.asp" name="Upload">
<input type="hidden" name="CopyrightInfo" value="http://www.chinaasp.com">
請選擇文件:<input type="file" name="file1" class="input"><br><br>
請選擇文件:<input type="file" name="file2" class="input"><br><br>
</form>
<br><br>
<a href="javascript:document.Upload.submit();"> 提 交 </a>
</center>


upload_file.asp
<%
on error resume next

'定義獲得文件後綴的函數
function getfileextname(filename)
pos=instrrev(filename,".")
if pos>0 then
getfileextname=mid(filename,pos+1)
else
getfileextname=""
end if
end function

'定義獲取文件正名的函數
function getfilename(filename)
lens=len(filename)-len(getfileextname(filename))-1
getfilename=left(filename,lens)
end function

'創建文件上傳組件的對象
set fileup=server.createobject("chinaasp.upload")

'循環讀取用戶上傳的文件,並保存在服務器上
for each f in fileup.files

'當用戶沒有選擇文件或文件大小超過10m時返回到選擇上傳文件的頁面
if f.filename="" or f.filesize>10485500 then response.redirect "upload_file.htm"

'獲取保存的路徑
path=server.mappath("upload_file.asp")
path=left(path,len(path)-15)

'保存文件
f.saveas path&getfilename(f.filename)&"."&getfileextname(f.filename)

next

response.redirect "upload_file.htm"
%>

TOP

5.驅動器/目錄/文件操作

本次交流時間有限,有時間再做詳細探討

6. Asp編寫與調試經驗:cookies和session如何選擇、cookies數量陷阱、頁面過期和緩衝設定、移植性如何保證、如何應付內部服務器500錯誤……

1.Cookies和Session的選擇:
.共同特點
.不同之處:
.工作方式
.過期條件
.對服務器的性能影響

2.Cookies數量陷阱:
IIS可以保存一般的cookies不超過20個,再定義新的Cookies以前的Cookies的值就丟失了,這樣對大型應用顯然局限性非常大,如何解決這個問題呢?
答案是使用二維Cookies。

例子:

測試一維Cookies數量極限:
test_cookies_1.asp
<%
for i=1 to 50
response.cookies("cookies_"&i)=i
next
%>


test_cookies_2.asp
<%
for i=1 to 50
response.write request.cookies("cookies_"&i)&"<br>"
next
%>

效果:
先訪問test_cookies_1.asp,再訪問test_cookies_2.asp,,發現了什麼?


test_cookies_3.asp
<%
for i=1 to 50
response.cookies("cookies_"&i)=i
next

for i=1 to 50
response.write request.cookies("cookies_"&i)&"<br>"
next
%>

效果:
沒有Cookies丟失!!!!

測試二維Cookies數量極限:
test_cookies_4.asp
<%
for i=1 to 301
response.cookies("tuht")("cookies_"&i)=i
next
%>


test_cookies_5.asp
<%
for i=1 to 301
response.write request.cookies("tuht")("cookies_"&i)&"<br>"
next
%>

效果:
使用這種方式可以使用201*20=4020個Cookies!!!!

3.頁面過期和緩衝設定
<%
'過期和緩衝處理
response.buffer=true
response.cachecontrol="no-chache"
response.expiresabsolute=now()-1
response.expires=0
%>
html中還可以做設定:
<meta content="no-cache" http-equiv="Pragma">
<meta HTTP-EQUIV="Expires" CONTENT="0">

4.移植性的保證
.包含文件
<!--#include file="top.asp" -->
.使用server.mappath尋找文件路徑,避免在頁面中直接使用絕對路徑
.盡量使用組件封裝業務邏輯

5.調試內部服務器500的錯誤
.設置IIS顯示具體的錯誤信息
.分步調試,由上而下
.打印某些重要的變量的值,檢查是否為我們預期
.根據經驗來判斷錯誤

7. 操作Word文檔

.安裝Office 2000,其中Word 2000必選
.設置IE中Internet的安全性:ActiveX控件和插件全部啟用
.設置工作目錄的文件權為Internet及System讀取/修改/寫入
.編寫模版course.dot
.具體代碼:
opr_doc_inc.asp
<%
Response.write "Dim Var_Num" & chr(13)
Response.write " Var_Num = 2 " & chr(13)
Response.write "Dim varstrings(2)" & chr(13)
Response.write "varstrings(0)=" & chr(34) & "起草人:" & chr(34) & chr(13)
Response.write "varstrings(1)=" & chr(34) & "日期:" & chr(34) & chr(13)
Response.write "Dim varValues(2)" & chr(13)
Response.write "varValues(0)=" & chr(34) &"起草人:塗海濤"& chr(34) & chr(13)
Response.write "varValues(1)=" & chr(34) & "日期:"&date()& chr(34) & chr(13)
%>

Sub instead(word)
Set myRange = word.ActiveDocument.Content
for i=0 to Var_Num - 1
call myRange.Find.Execute(varStrings(i),false,false,false,false,false,false,false,false,varValues(i),2)
Next
End Sub


opr_doc.asp
<%
'獲取保存的路徑
path=server.mappath("opr_doc.asp")
path=left(path,len(path)-11)
filenames=path&"test.doc"

w1="word.activedocument.saveAs"&chr(32)&chr(34)&filenames&chr(34)
w2="wApp.Documents.open"&chr(32)&chr(34)&filenames&chr(34)
%>
<script language="vbscript">
On Error Resume Next
'生成指定文件名的Word文檔
Dim word
set word = CreateObject("Word.Application")
if Err.number > 0 Then
Alert "發生錯誤,請確認文件是否存在"
else
word.visible = False
word.documents.open "<%response.write path%>course.dot"
<%Response.write w1%>
word.documents.close
set word=nothing
end if

<!--#include file="opr_doc_inc.asp"-->

Dim wApp
Set wApp = CreateObject("Word.Application")
If Err.number > 0 Then
Alert "發生錯誤,請確認文件是否正確創建"
else
wApp.visible = True
<%Response.write w2%>
call instead(wApp)
set wApp=nothing
end if
</script>

效果:看看生成了doc文件嗎?這個新建的doc文件和模版文件有什麼區別?起草人和日期發生了變化了嗎?保存一下,看看新生成的doc文件的內容。


附:
1.以上全部代碼在Windows 2000 Server SP2+IIS 5.0+MS SQL Server 2000+Office 2000下測試通過
2.配置數據庫:數據庫名course,用戶course_user,密碼course_password,ODBC驅動為course_dsn,端口為2433,描述表結構的腳本在共享目錄下。
3.Asp fileup、Jmail、Winzip 8.1、Winzip command line這幾個軟件請自行下載。
4.數據庫腳本文件:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[output_1]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[output_1]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[return_1]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[return_1]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[user_info_1]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[user_info_1]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[user_info_2]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[user_info_2]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[user_info_3]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[user_info_3]
GO

if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[user_info]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[user_info]
GO

CREATE TABLE [dbo].[user_info] (
[id] [int] IDENTITY (1, 1) NOT NULL ,
[user_name] [varchar] (40) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[password] [varchar] (20) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[user_info] WITH NOCHECK ADD
CONSTRAINT [PK_user_info] PRIMARY KEY CLUSTERED
(
[user_name]
) ON [PRIMARY]
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE [output_1]
@sid int output
AS
set @sid=2
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE [return_1]
(@user_name varchar(40),@password varchar(20))
AS
if exists(select id from user_info where user_name=@user_name and password=@password)
return 1
else
return 0
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE [user_info_1]
(@user_name varchar(40),@password varchar(20))
AS
select id from user_info where user_name=@user_name and password=@password
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE [user_info_2]
(@user_name varchar(40),@password varchar(20))
AS
SET XACT_ABORT ON
BEGIN TRANSACTION
delete from user_info where user_name=@user_name and password=@password
COMMIT TRANSACTION
SET XACT_ABORT OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS OFF
GO

CREATE PROCEDURE [user_info_3] AS
select * from user_info
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

TOP

發新話題

本站所有圖文均屬網友發表,僅代表作者的觀點與本站無關,如有侵權請通知版主會盡快刪除。