利用ASP改進文檔上載控件
隨著互聯網的發展,人們發布和獲取信息的方式發生了根本的變化,越來越多的人開始把網絡作為最重要的發布和獲取信息的途徑,同時,能發布并令信息共享的技術也越來越多。雖然這些技術為開發人員帶來了極大的便利,但是由于種種原因,其中有些技術還存在著這樣或那樣的缺陷。因此,開發人員在選擇和使用各種技術時,一定要認清這些技術的優點和局限性,取長補短,才能設計出功能完善的程序。 提出問題 筆者曾在建設企業內部信息網工程中開發過基于Web的文檔資源共享信息網站。該網站要求上載的文檔能自動在主頁中根據文檔的類別按文檔標題連接到對應的欄目里。針對這種需求,筆者利用IIS的文檔上載控件Posting Acceptor Components,結合數據庫和Web技術,開發出了一套自動化程度很高的文檔自動網頁發布系統和文檔自動網頁生成系統。在開發該系統的過程中,筆者發現IIS下的上載控件cpshost.dll在使用中存在一定的問題。例如,為完成上載,筆者開發了兩個程序:程序一(Upload.asp)提供基于Web的信息文檔上載錄入界面;程序二(wd_writer.asp)把程序一錄入的信息記錄到數據庫中。其中相關代碼如下: 程序一(upload.asp): …… ’提供文檔上載的客戶界面 <form enctype=“multipart/form-data” action=“http://<%= Request.ServerVariables (“SERVER_NAME”)%>/scripts/cpshost.dll?PUBLISH?wd_writer.asp” method=“post”> <p>文檔主題: <input type=“text” name=“subject”><br> 作者:<input name=“author” type=“text”><br> 發布時間: <input name=“date1” type=“text”><br> 上載文檔名(點擊瀏覽按鈕可進行選擇):<input type=“file” name=“filename”> Destination URL: <input type=“hidden” name=“TargetURL” value=“http://<%= Request.ServerVariables(“SERVER_NAME”)%>/users/wdls ”> <input type=“submit” value=“發布確定”> </p> </form> …… 程序二(wd_writer.asp): <%'打開數據庫 Set mydata = Server.CreateObject (“ADODB.Connection”) mydata.Open “DSN=xczh;UID=sa;PWD=;” '從表單中取出各項內容 date1=Request.form(“date1”) '取時間 '取文檔主題 subject=Request.form(“subject”) '取作者 author=Request.form(“subject”) '取文檔文件名 filename=Request.form(“filename”) '取文檔在Web服務器中存放的物理地址 TargetURL=Request.form(“filename”) '寫數據庫 sqlstr=“insert into wdlsb values(” & sn & “,‘” & subject & “',‘” & date1 & “',‘”& filename & “',‘” & TargetURL & “',‘” & author & “')” Mydata.Execute(sqlstr) %> 上述程序的語法結構和邏輯結構都正確無誤,但在使用時卻出現了問題。當在程序一中表單的subject 、Author、filename 域中填寫漢字后,在程序二中用Request取出的表單域值為亂碼,即不能正確從表單中取出域值。此時,表單進行POST請求服務時的域值的封裝模式(enctype)為“multipart/form-data”,即RFC 1867。于是筆者把程序一進行POST請求服務時的封裝模式修改為“text”,但卻出現了“無法上載文檔”的錯誤。筆者分析后發現,文檔上載控件cpshost.dll只能在表單的“multipart/form-data”封裝模式(既RFC 1867格式)下才能在瀏覽器與服務器之間進行文檔上載。 解決問題 筆者采用改變操作流程的方法,解決了上述問題。首先,由用戶填寫表單(程序三Upload.asp),并提交給程序四(wd_read.asp)進行預處理。在程序四中利用session對象暫時保存subject、author、date1、filename、targetUrl等表單域的輸入值。向用戶輸出一個確認頁面,由用戶再次確認表單。然后,設置表單的封裝模式為“multipart/form-data”,并進行上載操作。最后,由cpshost.dll調用程序五(wd_writer.asp)。由程序五取出存儲于內建對象session中的域值,進行數據庫操作和操作確認。如果程序四出現不可預測的錯誤,則文檔上載失敗,不會調用程序五,因此保持了數據庫的完整性。相關代碼如下: 程序三(upload.asp): <form action=“http://<%= Request. ServerVariables(“SERVER_NAME”)>/wd_read.asp” method=“post"> <p>文檔主題: <input type=“text” name=“subject”><br> 作者:<input name=“author” type=“text”><br> 發布時間: <input name=“date1” type=“text”><br> 上載文檔名(點擊瀏覽按鈕可進行選擇):<input type=“file” name=“filename”> Destination URL: <input type=“hidden” name=“TargetURL” value=“http://<%= Request .ServerVariables(“SERVER_NAME”)%>/users/<%=Request.ServerVariables(“LOGON_USER”) %>” size=“20”><br> <input type=“submit” value=“發布確定”> </p> </form> 程序四(wd-read.asp): <% '取出程序三中的表單域值并保存在session中 session(“subject”)=Request.form(“subject”) session(“date1”)=Request.form(“date1”) session(“author”)=Request.form(“author”) session(“filename”)=Request.form(“filename”) session(“TargetURL”)=Request.form(“TargetURL”) %> …… <form enctype=“multipart/form-data” action= “http://<%= Request.ServerVariables (“SERVER_NAME”) %>/scripts/cpshost.dll?PUBLISH?wd_writer.asp” method=“post”> 上載文件名(點擊瀏覽按鈕可進行選擇):<input type=“file” name=“filename” value=“<%=session(“filename”)%>”> <input type=“hidden” name=“TargetURL” value=“http://<%= Request.ServerVariables(“SERVER_NAME”) %>/users/wdls” > <input type=“submit” value=“發布確定”> </p> </form> 程序五(wd_writer.asp): <% '打開數據庫 Set mydata = Server.CreateObject (“ADODB.Connection”) mydata.Open “DSN=xczh;UID=sa;PWD=;” ’取各表單域的值 date1=session(“date1”) '取時間 subject=session(“subject”) '取文檔主題 author=session(“subject”) '取作者 filename=session(“filename”) '取文檔名 '取文檔在Web服務器中存放的物理地址 TargetURL= session(“TargetURL”) '寫數據庫,保存文檔記錄 sqlstr=“insert into wdlsb values(” & sn & “,‘”& subject & “',‘” & date1 & “',‘”& filename & “',‘” & TargetURL &“',‘” & author & “')” Mydata.Execute(sqlstr) %> 完善程序 上述程序雖然已經能滿足設計時的要求,但還是有需要完善的地方。例如,由于在程序三中輸入的文件名在程序四中會預置給表單域filename,所以,一旦客戶端重新輸入新的文件名后提交確認,會使程序五中寫入數據庫的文件名與實際上載的文件名不一致,造成網頁連接時出錯。為避免出現此類錯誤,在進行文檔上載時,應對表單域filename的值與程序三中的域值進行比較,如果兩者相等,立即進行文件上載,否則取消操作。相關代碼如下: 修改程序四(wd_read.asp): <form enctype=“multipart/form-data” action=“http://<%= Request.ServerVariables (“SERVER_NAME”) %>/scripts/cpshost.dll?PUBLISH?wd_writer.asp” method=“post” name=“form1”> 上載文檔名(點擊瀏覽按鈕可進行選擇):<input type=“file” name=“filename” value=“<%=session(“filename”)%>”> <input type=“hidden” name=“TargetURL” value=“http://<%= Request.ServerVariables (“SERVER_NAME”) %>/users/wdls” > ’把表單中的按鈕改為‘button’模式,變成普通按鈕,當點擊時,執行腳本程序upload_onclick <input type=“button” name=“upload” value=“發布確定”> </form> ’對表單域filename的值進行判斷 <scripts language=“VBScript”> <!-- sub upload_onclick() set myform=window.document.form1 tmp=myform.filename.value if strcomp(tmp,<%=session (“filename”)%>)=0 then form1.submit else msgbox “輸入的文件名有誤,請返回重新輸入。!” end if end sub --> </scripts> 經過上述改進后,系統運轉平穩可靠,縮短了信息上網周期,大大地提高了文檔的上網效率。該系統完整的程序中還包括對用戶口令和權限的驗證、文檔主題是否為空的驗證、作者域驗證、文檔的分類選擇、上載文檔重名的驗證、數據庫操作的異常處理等。
|