各位前輩好,日前有詢問了一個問題[ASP] 加上onbeforeunload後,匯出的Excel檔變成無法打開?,後來有其他網友建議可以使用Global.asa的Session_OnStart及Session_OnEnd來處理匯出時建立使用者資料夾,登出後刪除使用者資料夾的動作,來完成我的目的。
目前我的狀況如下:
login.asp
session.timeout=1440
session("EMPLOYEECODE")=rs("EMPLOYEECODE")
Global.asa
<script language="vbscript" runat="server">
Sub Application_OnStart
Application("Fdr") = Server.MapPath("\export\")
End Sub
Sub Session_OnStart
Application("Fdr") = Application("Fdr") & "\" & session("EMPLOYEECODE")
Set fs = CreateObject("Scripting.FileSystemObject")
If Not fs.FolderExists(Application("Fdr")) Then
fs.CreateFolder (Application("Fdr"))
End If
End Sub
</script>
這樣並不會成功建立使用者工號的資料夾,但若是使用
Application("Fdr") = Application("Fdr") & "\test"
則會成功建立test資料夾,請問該如何在登入後可以建立使用者資料夾呢?
謝謝!
你ASP的觀念錯了
Global.asa 的 Sub Session_OnStart
並不是你登入後才跑的 (記得是連線建立成功後就會跑到)
所以你要把檢查與建立資料夾的Code
搬到處理登入成功的地方( 例如 login.asp )
還有
Application 的變數使用時
最好Lock住
用完再Unlock
免得多工下,同時修改導致錯亂
把這個放在你處理登入成功的地方看看, 請改用Session("Fdr") 來記錄每個人的資料夾名稱, 至於Application("Fdr")就別再改它的內容了
Session("Fdr") = Application("Fdr") & "\" & Session("EMPLOYEECODE")
Set fs = CreateObject("Scripting.FileSystemObject")
If Not fs.FolderExists(Session("Fdr")) Then
fs.CreateFolder (Session("Fdr"))
End If
感謝player大的回覆!
那這樣其實應該用不到Global.asa,我就把建立資料夾的code放到login.asp的地方,把刪除資料夾的code放到logout.asp感覺也可以達到我要的目的,但是session逾時的時候,刪除資料夾的程式又應該如何撰寫呢?
還是說刪除資料夾的程式,就應該要寫在Global.asa的Session_OnEnd裡,此時我login.asp所設定的Session("EMPLOYEECODE")就會有值可以抓取了?
對, 放在Session_OnEnd裡面刪除
但是ASP的Session機制其實很不穩定
當IIS中途掛掉時,Session_OnEnd就不會跑到
所以你還是得每個月手動刪除資料夾
今天研究登入逾時刪除資料夾的部分失敗,
<script language="vbscript" runat="server">
Sub Session_OnEnd
Fdr = Server.Mappath("\export\1")
'刪除使用者暫存資料夾
Set Fso = Server.CreateObject("Scripting.FileSystemObject" )
If Fso.FolderExists(Fdr) Then '若資料夾存在,則刪除資料夾
Fso.Deletefolder Fdr,true
End If
Set Fso = Nothing
End Sub
</script>
我手動新增一個"1"資料夾,測試登出後只有刪除使用者資料夾,"1"資料夾卻都還在,但有時又會不明原因自己消失。然後把IIS的連線逾時改為60秒,Session.Timeout=1,等了至少有5分鐘,結果Seesion也都還在,於是直接按登出,"1"資料夾也還是在。
然後有其他網友說,並不能精確的控制Session_OnStart及Session_OnEnd的時機,
一般"登入逾時"是不會做什麼動作,或者也可以在登入後,先刪除舊的暫存資料夾在新增新的。
請問player大我是不是哪裡做錯了?還是可以採用其他網友的建議呢? 謝謝!
你處理登出的地方
到底有沒有用
Session.Abandon()
沒有的話,並不會馬上跑Session_OnEnd
而是會等到Session TimeOut 或是WebServer收到連線斷掉的通知才會跑到
因看到Session_OnEnd不能使用Server.Mappath,修改Fdr的變數值
Fdr = "C:\inetpub\wwwroot\export\1"
也還是沒有作用,= =
非常抱歉,player大,我是用
Session.Contents.RemoveAll()
剛剛使用
Session.Abandon()
的確可以達成我要的目的了,稍早也有用到此語法但是不成功,可能是我語法輸入錯誤,少加到括號,真是非常感謝!
那其實用Session.Abandon()也就等於是Session TimeOut的效果了嗎?這樣問用意是想說我就不用測試Session Timeout會不會刪除資料夾了。
只是我也不解,為啥我IIS已經設定60秒逾時,Session.Timeout=1(分鐘),卻都還不會生效?還是因為我網址設定http://localhost:81/login/login.asp 的原因?
謝謝!
Asptlb.tlb 裡關於Session的說明
[id(0x60020004), propget, helpstring("Specifies the timeout period assigned to the Session object for this Application, in minutes.")]
HRESULT Timeout([out, retval] long* plvar);
[id(0x60020004), propput, helpstring("Specifies the timeout period assigned to the Session object for this Application, in minutes.")]
HRESULT Timeout([in] long plvar);
[id(0x60020006), helpstring("Destroys a Session object and releases its resources.")]
HRESULT Abandon();
其他Asptlb.tlb的說明
http://www.player.idv.tw/prog/index.php/Asptlb.tlb
Session Timeout 沒照預期的原因很多
例如你設1
可是你的瀏覽器在60秒內還在存取 (有可能會受到瀏覽器外掛或掃毒的影響)
或是Web Server上的設定問題
ASP的Session Timeout
比ASP.NET的Session Timeout還要更不準時
當連線沒斷掉時,有時候Session會一直保存在那裏,不會Timeout
例如你有透過Proxy的話
後來Global.asa改成如下,也可在登出時,刪除使用者暫存資料夾:
<script language="vbscript" runat="server">
Sub Application_OnStart
Application("Fdr") = Server.MapPath("\export\")
End Sub
Sub Session_OnEnd
Application.Lock
Fdr = Application("Fdr")& "\" & session("EMPLOYEECODE")
Application.UnLock
'刪除使用者暫存資料夾
Set Fso = Server.CreateObject("Scripting.FileSystemObject" )
If Fso.FolderExists(Fdr) Then '若資料夾存在,則刪除資料夾
Fso.Deletefolder Fdr,true
End If
Set Fso = Nothing
End Sub
</script>
但是在實際測試若工作逾時,能不能使Session_OnEnd生效部分,遇到問題,始終測試不出來。不管是DefaultAppPool及ASP的工作階段逾時皆有調整為3~4分鐘逾時,結果等了30分~甚至2小時以上都還不逾時,且發現將瀏覽器關閉Session會不見,網路有文章說session還會留在伺服器上),因此不會觸發Session_OnEnd事件。
因此我在想說,是不是乾脆簡單化,登入時檢查暫存資料夾在不在,在就先刪除再新增,不在就直接新增。
先跟player大說聲抱歉,你幫忙了這麼久,最後有可能不使用Global.asa的方法運作。
在失望之餘,我想不透為什麼不會Timeout的時候,突然看到top.asp好像有一段程式,會一直執行:
//線上狀態
function show_location() {
$.post("../online.asp");
setTimeout('show_location()',30000);
}
show_location();
setTimeout會每3秒就讀取online.asp,其中online.asp會讀取到session值,也就導致session不會timeout。
然後在思考整個運作流程後,我決定Session_OnEnd刪除使用者暫存資料夾,及登入時檢查資料夾使否存在並行,
一來可以解決您說的某帳號很久未「登入」的情況,
二來若使用者直接關閉網頁,且在Timeout前又再次登入,登入前檢查資料夾是否存在就可派上用場。
原本想做成關閉網頁觸發事件(onunload、onbeforeunload或者其他的),然後導向到logout.asp去觸發Session.Abandon(),不是瀏覽器不支援,就是結果不理想,要再想辦去排除那些問題,感覺很花時間所以作罷。
問題總算是解決了,感謝player大一路相助。