2009-06-06 33 views
6

Tôi đã tạo một hệ thống đăng nhập bằng php với chức năng đăng xuất vv Nhưng tôi cần phiên bị hủy khi đóng cửa sổ. Điều này cần phải là "tức thời" hoặc nhanh nhất có thể để thay đổi trạng thái người dùng thành ngoại tuyến. Tôi không thực sự muốn đặt một thời gian trên phiên làm việc vì điều này gây khó chịu cho người dùng phải đăng nhập tất cả thời gian.hủy phiên trên cửa sổ đóng?

Bất kỳ đề xuất nào được hoan nghênh, cảm ơn. =)

Trả lời

6

Theo mặc định, tất cả cookie phiên do PHP gửi sẽ bị xóa khi đóng trình duyệt. Nhưng theo tôi thấy, bạn muốn hiển thị thông báo trên các trình duyệt khác. Đây là một chút khó khăn hơn và không khá tốt đẹp. Bạn sẽ phải sử dụng trình xử lý sự kiện window.onclose và đưa ra yêu cầu Ajax (tôi tin rằng nó phải là một yêu cầu đồng bộ) đến máy chủ để báo hiệu việc đóng cửa sổ. Và các cuộc gọi đồng bộ không đẹp như vậy ...

Mặt khác, trình duyệt khác sẽ phải kéo máy chủ với yêu cầu Ajax khác để xem thời điểm một người dùng nhất định đã đăng xuất.

Tất cả các yêu cầu Ajax này đưa ra giải pháp xấu.

Cập nhật:

Như Thorarin và Jonathan Fingland nói, có thể có vấn đề với nhiều cửa sổ (không tab, như cháy window.onclose trên cửa sổ không tab), nhưng tôi tin rằng có một giải pháp cho vấn đề này quá. Nếu cửa sổ đầu tiên đặt cookie number_of_windows = 1, được tăng lên cho mỗi cửa sổ đã mở, sau đó đóng cửa sổ, yêu cầu Ajax chỉ được kích hoạt nếu number_of_windows bằng 1, nếu không thì chỉ cần giảm number_of_windows.

Cập nhật 2:

Các giải pháp trên sẽ, quả thật vậy, có vấn đề với nhiều tab mở. Tôi đang nghĩ làm thế nào để giảm bớt điều đó.

Cập nhật 3:

OK, tôi đã tìm ra một số loại giải pháp nhưng nó không làm việc trong IE6, không biết gì về phiên bản IE khác. Đoạn mã dưới đây theo dõi số lượng cửa sổ và tab đang mở (ngoại trừ IE không cập nhật document.cookie trong thời gian thực giữa các cửa sổ, nhưng tôi tin rằng nó có thể được giải quyết bằng một số tính năng độc quyền của IE). Sau đó, trên mỗi trang unload, có nghĩa là thậm chí điều hướng từ trang này sang trang khác trên cùng một trang web, kịch bản kiểm tra để xem có bao nhiêu cửa sổ đang mở. Nếu đó là cửa sổ/tab mở duy nhất, thì nó phát ra một yêu cầu Ajax. Đây là phần đầu tiên của giải pháp. Bây giờ, phần thứ hai.

Ở phía máy chủ, tập lệnh mà cuộc gọi Ajax đang yêu cầu, nên cập nhật một số mục nhập trong DB cho biết người dùng có thể đã đóng trang. Làm thế nào để bạn biết liệu cô ấy không chỉ truy cập một trang mới trên trang web của bạn? Đơn giản, trên mỗi lần truy cập trang, bạn kiểm tra DB cho các giá trị "có thể đăng xuất" cho phiên đó và nếu bạn gắn cờ chúng là false (người dùng đã đăng nhập), nếu không người dùng sẽ bị đăng xuất trong DB (đúng cờ).

Thật lộn xộn nhưng đó là giải pháp duy nhất xuất hiện trong tâm trí của tôi, vì không có cách nào tôi có thể xác định tải lại trang hoặc tương tự trong JavaScript. Ngoài ra, tôi đã không làm thử nghiệm rộng rãi, là một ý tưởng. Dù sao, Tôi sẽ không đề xuất giải pháp này. Một yêu cầu Ajax cho mỗi trang thay đổi là quá mức cần thiết và theo nghĩa đen tăng gấp đôi số lần truy cập trên máy chủ, mà không tính số lần bỏ phiếu được thực hiện bởi các trình duyệt khác.

Đây là đoạn trích. Nhân tiện, bakery.js là một trình bao bọc nhỏ cho document.cookie. Bạn có thể tìm thấy its source here on github.

<!DOCTYPE html> 

<html> 
<head> 
<meta charset="UTF-8"> 
<title></title> 
<script type="text/javascript" src="bakery.js"></script> 
<script type="text/javascript"> 
var logout = function() { 
    var xhr = new XMLHttpRequest; 
    xhr.open("GET", "logout.php", false); 
    xhr.send(null); 
}; 

window.onload = function() { 
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0; 
    IGS.Bakery.setCookie("winNumber", winNumber + 1); 
}; 

window.onunload = function() { 
    var winNumber = parseInt(IGS.Bakery.getCookie("winNumber"), 10) || 0; 
    IGS.Bakery.setCookie("winNumber", winNumber - 1); 

    if (winNumber === 1) { 
     logout(); 
    } 
}; 

var showCookies = function() { 
    alert(IGS.Bakery.getCookie("winNumber")); 
}; 
</script> 
</head> 
<body> 

<a href="#" onclick="showCookies();">show</a> 

</body> 
</html> 

Quên đề cập đến. window.onclose không phải là trình duyệt chéo.

+1

cũng không làm việc một cách đáng tin cậy như được chỉ ra trong ví dụ của thorarin vì nhiều cửa sổ/tab có thể được mở trên cùng một trang. người đầu tiên đóng cửa sẽ dẫn đến phiên bị giết –

+0

Cảm ơn đề xuất của bạn – Elliott

+0

@ Jonathan Fingland, tôi đã cập nhật câu trả lời của mình bằng một giải pháp tiềm năng. Đang chờ phản hồi. –

3

Bạn có thể sử dụng JavaScript để triển khai sự kiện OnUnload và sử dụng AJAX để liên lạc với người dùng rời khỏi trang web. Tuy nhiên, sự kiện này cũng xảy ra khi họ điều hướng đến một trang khác. Bạn sẽ phải thực hiện một cái gì đó như "nếu người dùng không yêu cầu một trang mới trong vòng x giây", anh ta đã rời khỏi trang web của tôi, nhưng nó sẽ không bao giờ hoạt động đáng tin cậy nếu bạn tính đến khả năng nhiều cửa sổ đang mở.

Cách duy nhất để thực hiện việc này, là thực hiện đăng lại AJAX thông thường với máy chủ mà người dùng vẫn ở trên trang của bạn. Nó vẫn sẽ không được ngay lập tức mặc dù.

Bạn có thể thử thử nghiệm với tập lệnh bạn đăng lại. Xây dựng trong thời gian chờ đợi đáng kể trước khi trả lời. Khi người dùng điều hướng khỏi trang của bạn, trình duyệt sẽ có thể hủy bỏ XmlHttpRequest đang diễn ra. Kịch bản phía máy chủ của bạn có thể đăng ký khách hàng ngắt kết nối và kết luận rằng người dùng đã rời khỏi ... một lần nữa, trừ khi họ tiếp tục tải trang khác.

Tóm lại, không có cách xác định nào để thực hiện điều này một cách rõ ràng.

+0

Ok cảm ơn, thats đã cho tôi một ý tưởng tốt hơn tôi didnt nghĩ rằng sẽ có một "cách dễ dàng". – Elliott

1

Bạn có thể tách các khái niệm "hiển thị là đã đăng nhập" thực sự đang đăng nhập. Ví dụ: mỗi lần người dùng yêu cầu trang, bạn có thể đánh dấu trang là "trực tuyến" trong vài phút nữa. thời gian chờ vài giờ. Trong chương trình này nếu người dùng rời khỏi máy tính của họ, trang web sẽ hiển thị chúng dưới dạng "ngoại tuyến" sau một vài phút nhưng họ vẫn có thể quay lại sau một giờ hoặc lâu hơn và không phải đăng nhập lại.

Các vấn đề liên quan