2010-06-29 165 views
31

基本上,一旦用戶在我的應用程序中離開網頁,我需要用AJAX調用PHP腳本,這會在網頁中插入一段時間到數據庫然後離開頁面。

等待AJAX​​請求完成是非常重要的,因爲我的應用程序中的網頁不能被用戶訪問,除非他們在前一頁上花了一定時間(比如說兩分鐘)。

這裏是我的jQuery代碼:

$(document).ready(function() { 

    var teid = TEID; 
    var startTime = new Date().getTime(); 

    $(window).unload(function() { 
     var timeSpentMilliseconds = new Date().getTime() - startTime; 
     var t = timeSpentMilliseconds/1000/60; 

     $.ajax({ 
      type: 'POST', 
      url: '/clientarea/utils/record-time', 
      data: 'teid=' + teid + '&t=' + t 
     }); 
    }); 

}); 

我應該如何改變它,所以它會等待AJAX​​請求離開網頁之前結束?

編輯:

或者,它可能會更好(容易)只是讓AJAX請求重複每分鐘左右。那可能嗎?

回答

30

那麼,您可以在您的AJAX調用中設置async: false,以使瀏覽器在做任何事情之前等待請求完成,但請注意,這會在請求期間「掛起」瀏覽器。

$.ajax({ 
    type: 'POST', 
    async: false, 
    url: '/clientarea/utils/record-time', 
    data: 'teid=' + teid + '&t=' + t 
}); 

從手冊:

缺省情況下,所有的請求被髮送異步(即這是通過默認設置爲true)。如果您需要同步請求,請將此選項設置爲false。跨域請求和dataType:「jsonp」請求不支持同步操作。請注意,同步請求可能會暫時鎖定瀏覽器,並在請求處於活動狀態時禁用任何操作。

+0

嗯。謝謝。我更新了我的問題。只要讓AJX請求重複一遍就可以輕鬆一點。我會怎麼做? – 2010-06-29 07:06:19

+12

我強烈建議避免這種情況,**特別**關於'卸載'。 – jAndy 2010-06-29 07:06:36

+0

我發現總是有一個比'async:false'更好的解決方案,不管問題是什麼。 – 2015-02-11 22:31:23

4

對我來說,你是不是瀏覽器關閉之前等待......是個好主意
簡單,因爲如果我真的要關閉它?什麼......

如果一個網頁煩一個用戶,它不好...

我的建議是,在頁面上,你等待2分鐘(如果2分鐘是要求),然後發送一個Ajax,用戶已經完成了他的2分鐘...

然後你可以在服務器端檢查它,如果一個有他的2分鐘或不...

0

jQuery.ajax()方法有選項async。如果將其設置爲false,則呼叫將阻塞,直到響應返回(或超時)。我真的很舒服,調用這個,會使瀏覽器在卸載處理程序中變得糟糕。

附註:你不能依靠這個工作。如果瀏覽器允許用戶選擇取消卸載處理程序(某些瀏覽器在等待一段時間後執行),則「網站停留時間」將不會更新。您可以在網站上添加一個定時器,定期調用服務器上的腳本並更新時間。你不會有一個準確的價值,但在你的情況下,這是不需要的。

如果您只需要知道用戶是否在頁面上有X秒您可以簡單地在onload處理程序中設置超時(使用setTimeout(function, ms)),如果用戶已花費所需時間,則會發出呼叫。所以不需要卸載處理程序。

1

使用onbeforeunload

$(document).ready(function(){ 
    window.onbeforeunload = function(){ 
    // $.ajax stuff here 
    return false; 
    } 
}); 

這至少會帶給用戶messagebox,詢問他是否要關閉當前窗口/標籤。

1

我認爲使用輪詢技術會更好,正如您所建議的那樣,儘管它會在Web服務器上造成一些負載。

$(document).ready(function() { 

    var teid = TEID; 
    var startTime = new Date().getTime(); 

    var ajaxFunc = function() { 
     var timeSpentMilliseconds = new Date().getTime() - startTime; 
     var t = timeSpentMilliseconds/1000/60; 

     $.ajax({ 
      type: 'POST', 
      url: '/clientarea/utils/record-time', 
      data: 'teid=' + teid + '&t=' + t 
     }); 
    }; 

    setInterval(ajaxFunc, 60000); 

}) 

你會很高興的時候可以使用WebSockets :)

+0

謝謝。但這隻會在一分鐘後執行一次?它能否每分鐘重複執行一次(60秒)? – 2010-06-29 07:33:50

+2

這就是setInterval所做的,而不是setTimeout – sje397 2010-06-29 12:44:40

2

這是一個壞主意,試圖劫持用戶的瀏覽器,因爲這會給他們一種不好的預感,並送他們離開。

如果出於某種原因,如果用戶在前一次花費最少時間之前不想生成新頁面,則最好的做法是嘗試服務器端,即重定向到當前頁面直到請求的時間已經過去了。

您甚至不需要進行ajax調用,只需在會話中存儲提供頁面的時間戳,並且在經過一段時間後才顯示下一頁。

一定要告訴用戶,他們必須等待一個新的頁面準備好,也許只需一個簡單的javascript倒計時。

如果您希望用戶確實將頁面激活了一段時間(即不會切換到等待兩分鐘的另一個頁面/窗口),那麼我無法提出有效的解決方案。

6

如何在卸載處理程序中設置cookie?服務器應該在隨後的請求中看到它。

<script> 
    $(window).unload(function(){document.cookie='left_on='+(new Date())}) 
</script> 
7

最好的解決辦法是使用navigator.sendBeacon。這是全新的功能,正在開始在新版本的瀏覽器中實現。該功能在Chrome 39和Firefox 31以上的瀏覽器中可用。本文撰寫本文時,Internet Explorer和Safari不支持此功能。爲確保您的請求在尚不支持新功能的瀏覽器中發送,您可以使用此解決方案:

var navigator.sendBeacon = navigator.sendBeacon || function (url, data) { 
    var client = new XMLHttpRequest(); 
    client.open("POST", url, false); // third parameter indicates sync xhr 
    client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); 
    client.send(data); 
}; 

希望這有助於您!

+0

我認爲這是優雅的,我用它在Electron中發送數據時應用程序關閉 – furiel 2017-01-13 17:44:09

+0

2018年,這是要走的路。 – Baishu 2018-02-24 08:27:59

相關問題