iT邦幫忙

1

[ASP] Global.asa 如何取得SESSION變數值,以便登入後,可以建立使用者資料夾?

各位前輩好,日前有詢問了一個問題[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資料夾,請問該如何在登入後可以建立使用者資料夾呢?

謝謝!

1 個回答

0
player
iT邦大師 1 級 ‧ 2020-07-22 22:25:13
最佳解答

你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
看更多先前的回應...收起先前的回應...
b7307024 iT邦新手 4 級 ‧ 2020-07-22 23:11:50 檢舉

感謝player大的回覆!

那這樣其實應該用不到Global.asa,我就把建立資料夾的code放到login.asp的地方,把刪除資料夾的code放到logout.asp感覺也可以達到我要的目的,但是session逾時的時候,刪除資料夾的程式又應該如何撰寫呢?

還是說刪除資料夾的程式,就應該要寫在Global.asa的Session_OnEnd裡,此時我login.asp所設定的Session("EMPLOYEECODE")就會有值可以抓取了?

player iT邦大師 1 級 ‧ 2020-07-23 00:09:34 檢舉

對, 放在Session_OnEnd裡面刪除
但是ASP的Session機制其實很不穩定
當IIS中途掛掉時,Session_OnEnd就不會跑到
所以你還是得每個月手動刪除資料夾

b7307024 iT邦新手 4 級 ‧ 2020-08-13 18:01:17 檢舉

今天研究登入逾時刪除資料夾的部分失敗,

<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大我是不是哪裡做錯了?還是可以採用其他網友的建議呢? 謝謝!

player iT邦大師 1 級 ‧ 2020-08-13 18:20:15 檢舉

你處理登出的地方
到底有沒有用
Session.Abandon()
沒有的話,並不會馬上跑Session_OnEnd
而是會等到Session TimeOut 或是WebServer收到連線斷掉的通知才會跑到

b7307024 iT邦新手 4 級 ‧ 2020-08-13 18:22:24 檢舉

因看到Session_OnEnd不能使用Server.Mappath,修改Fdr的變數值

Fdr = "C:\inetpub\wwwroot\export\1" 

也還是沒有作用,= =

b7307024 iT邦新手 4 級 ‧ 2020-08-13 18:39:19 檢舉

非常抱歉,player大,我是用

Session.Contents.RemoveAll()

剛剛使用

Session.Abandon()

的確可以達成我要的目的了,稍早也有用到此語法但是不成功,可能是我語法輸入錯誤,少加到括號,真是非常感謝!
/images/emoticon/emoticon01.gif

那其實用Session.Abandon()也就等於是Session TimeOut的效果了嗎?這樣問用意是想說我就不用測試Session Timeout會不會刪除資料夾了。

只是我也不解,為啥我IIS已經設定60秒逾時,Session.Timeout=1(分鐘),卻都還不會生效?還是因為我網址設定http://localhost:81/login/login.asp 的原因?

謝謝!

player iT邦大師 1 級 ‧ 2020-08-13 18:46:38 檢舉

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

b7307024 iT邦新手 4 級 ‧ 2020-08-13 20:04:45 檢舉

player大,抱歉,我不懂你要表達的是什麼?

關於我在本機無法逾時的部分,我參照此教學連結嘗試修改Win7 IIS 7.5的設定,試了老半天,還是不能實現工作逾時的狀況,殘念~ /images/emoticon/emoticon06.gif

player iT邦大師 1 級 ‧ 2020-08-14 16:08:39 檢舉

Session Timeout 沒照預期的原因很多
例如你設1
可是你的瀏覽器在60秒內還在存取 (有可能會受到瀏覽器外掛或掃毒的影響)
或是Web Server上的設定問題
ASP的Session Timeout
比ASP.NET的Session Timeout還要更不準時
當連線沒斷掉時,有時候Session會一直保存在那裏,不會Timeout
例如你有透過Proxy的話

b7307024 iT邦新手 4 級 ‧ 2020-08-17 13:33:52 檢舉

後來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的方法運作。/images/emoticon/emoticon70.gif

b7307024 iT邦新手 4 級 ‧ 2020-08-20 14:14:02 檢舉

在失望之餘,我想不透為什麼不會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大一路相助。

我要發表回答

立即登入回答