2010-08-27 25 views
35

我需要一種監視用戶編輯會話的方法,並且我正在審閱的其中一個解決方案將使我使用unload事件發送ajax請求,以通知服務器編輯會話結束。 (請參閱:Monitoring User Sessions to Prevent Editing Conflict可以使用卸載事件來可靠地啓動ajax請求嗎?

我對unload事件的讀取(相當有限)表明附加到此處理程序的代碼必須快速運行,因此通常用於清除對象以防止內存泄漏。

我的問題是,這可以爲此目的可靠工作嗎?

PS。我知道async: false選項。

回答

35

如果您的服務器速度足以響應,此方法相當可靠。雖然有些事情要真正注意。如果關閉瀏覽器並在卸載事件時發送AJAX請求,那麼很有可能在窗口對象被銷燬之前,響應不會及時從服務器返回。在這種情況下(至少在IE中)會發生什麼情況是它將孤立你的連接對象,並且在連接超時命中之前不會正確終止它。如果您的服務器沒有啓用連接保持活動狀態,則在關閉2個窗口(同時仍打開另一個窗口)後,您將用完打開的服務器連接(對於IE6-7,對於IE8-6窗口)直到連接超時被打中,您將無法打開您的網站。

我遇到過這樣的情況,之前我打開一個彈出窗口,在卸載時發送了一個AJAX請求,這非常可靠,但它受到上述發佈的困擾,並且花了很長時間我跟蹤它並瞭解發生了什麼。之後,我做了什麼,我確保打開的窗口將具有相同的代碼來調用服務器,並在每次卸載時檢查開啓器,並在其中運行代碼(如果存在)。

看來,如果關閉最後一個瀏覽器窗口,IE將正確銷燬連接,但如果另一個窗口打開,則不會。

P.S.只是爲了評論上面的答案,AJAX並不是真正的異步。至少JS的實現不是。發送請求後,您的JS代碼仍將等待服務器的響應。它不會阻止你的代碼執行,但是由於服務器可能需要一段時間才能響應(或者足夠長的時間讓Windows終止IE窗口對象),你可能會碰到上述問題。

+1

有沒有人試過這與異步關閉?我猜這會阻止瀏覽器卸載,直到請求返回。 – 2011-11-02 17:14:04

+3

這是正確的。在關閉異步的情況下,瀏覽器將在卸載頁面之前等待來自服務器的響應。這有助於解決Chrome瀏覽器問題,在卸載事件和異步操作時,Chrome非常不可靠。這也將解決我上面描述的IE連接佔用問題。但它會是用戶可見的。 – 2011-11-04 19:08:33

+2

值得關注具有'Navigator.sendBeacon'的新Beacon API,它將允許更好的方式在卸載時可靠地向我們的服務器發出異步請求:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon – Wildhoney 2015-03-31 14:59:17

1

您必須自己測試一下您的特定場景是否符合unload的規定,但由於AJAX是異步的,所以AJAX請求非常快。您只需發送請求,然後就完成了! (也許你必須清除你剛創建的請求對象,但是)。

如果你想驗證AJAX請求做了它,那麼你不必擔心更多/使用async:false選項(如this discussion指示)。但是,發送只是一個快速的繁榮 - 你完成的操作。

+1

好吧,我不會把它可靠的,如果它無法到達服務器,對不對? ;) – 2010-08-27 16:31:07

+1

的確如此,但我認爲你的意思是可靠的,因爲瀏覽器實際上會發送請求。 – palswim 2010-08-27 16:48:03

3

我們有我們需要的情況。這是一個需要在服務器上留下嚴重內存的報告頁面,所以我們希望在他們離開頁面後立即將其釋放。我們創建了一個框架並在那裏添加了卸載處理程序。最可靠的方法是將圖像的src設置爲釋放腳本。實際上,我們使用unload和onbeforeunload來實現跨瀏覽器兼容性。它沒有在網絡工具包的夜晚工作,但管理是確定的。

但是,這不是我提出的解決方案。我會使用心跳方法,其中涉及更多的工作,但更強大。

您的頁面應發出定期心跳請求。每個請求都會設置來自頁面的最後一次心跳。然後,您需要一個在服務器上運行的線程,並在最後一次檢測信號太早之前清除內存。

這並不能解決長時間離開頁面的問題。爲此,您需要對用戶活動進行一些監控,並在一段時間不活動後離開該頁面(請確保您已與用戶確認)。

+0

你真的*需要'frameset',圖像和釋放腳本方法嗎?它似乎相當黑客......或者比使用兩個「卸載」事件更可靠? – 2010-08-29 02:40:23

+0

我們需要框架集,因爲導航是在頁面內進行的,我們只想在離開頁面集合時發送「空閒內存」請求。 image/two-unload方法是我們在瀏覽器和操作系統中最可靠運行的方式。 – 2010-08-30 14:47:47

12

您是否嘗試過使用

var i = new Image(1,1); 
i.src='http://...' 

而剛剛返回從服務器的一些空的圖像。我認爲它應該是可靠的,腳本會阻止。順便說一句:很高興添加時間戳以防止緩存。

+0

我發現在onload事件函數中的AJAX調用不起作用,但是這種方法做到了。應該注意的是,功能代碼不會停止或阻止頁面卸載,代碼可能在頁面卸載後執行。 – nuander 2016-08-22 16:34:06

-2

我有一種情況,我只需要通知服務器端有關卸載並不關心響應。

如果那是你的情況,你可以ignore_user_abort,然後你知道它會發生「可靠」

相關問題