javascript - 使用ajax强制注销时数据库表未更新
问题描述
如标题中所述,当 30 分钟内没有任何活动发生时,数据库表trace_users
不会更新,但在 6 分钟内会更新。
以下代码(JS 和 PHP)位于同一个 php 文件mno.php中。
我通过let lastActivity = <?php echo time(); ?> ;
下面脚本中的这一行存储用户的最后一个活动。
<?php
session_start();
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
session_destroy(); // destroy session data in storage
!isset($_SESSION['admin']);
$open = "false";
$write = "0";
$stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
$stmt->bind_param('sss', $open, $write, $usname);
$stmt->execute();
}
?>
<script>
jQuery(document).ready(function($) {
let lastActivity = <?php echo time(); ?> ; // storing last activity of user
let now = <?php echo time(); ?> ;
let logoutAfter = 360;
let timer = setInterval(function() {
now++;
let delta = now - lastActivity;
console.log(delta);
if (delta > logoutAfter) {
clearInterval(timer);
//DO AJAX REQUEST TO close.php
$.ajax({
url: "/abc/mno.php",
type: 'GET',
data: {
action: 'logout'
}, // Line A
success: function(data) {
console.log(data); // Line B
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
});
}
}, 1000);
});
</script>
问题陈述:
我想知道我应该在上面的代码中进行哪些更改,以便在 30 分钟(1800 秒)内没有任何活动发生时,数据库表也应该得到更新。
Case1(不工作): 1800 秒(页面注销,数据库不更新)
Case2(工作): 360 秒(页面注销,数据库更新)
session.gc_maxlifetime 里面的值是 1440(Local Value) 1440(Master Value)
这是我尝试过/调试过的:
在网络选项卡上,当会话超时设置为6 mins和60 mins时,我得到了 Request Method GET。
解决方案
您需要向 javascript 传递某种永久 UID,即使在会话过期后也能识别用户。
为了简化起见,我正在使用user_name
您的代码中已经存在的那个。但是您也可以为每个用户分配一个 UUID,这样就无法猜测另一个用户的名称,也无法修改他们的统计信息。
首先,您将把$_SESSION['user_name']
from PHP 传递给 JS 闭包。
let userName = "<?php echo $_SESSION['user_name']; ?>"; // don't forget to wrap the JS string value in quotes or apostrophes
然后,您将在 AJAX 请求负载中传递它。
data: {
action: 'logout',
user_name: userName // added param
},
最后,您将覆盖发送到 DB 的值(如果它与有效负载一起发送)
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : ''; // original line
if (isset($_GET['user_name']) && !empty($_GET['user_name'])) {
$usname = $_GET['user_name'];
}
$stmt->bind_param('sss', $open, $write, $usname); // original line
完整更新代码:
<?php
if (isset($_GET['action']) && $_GET['action'] == "logout")
{
session_destroy(); // destroy session data in storage
!isset($_SESSION['pageadmin']);
$open = "false";
$write = "0";
$stmt = $connect->prepare("UPDATE trace_users SET open=?, write=? WHERE user_name=?");
$usname = !empty($_SESSION['user_name']) ? $_SESSION['user_name'] : '';
if (isset($_GET['user_name']) && !empty($_GET['user_name'])) {
$usname = $_GET['user_name'];
}
$stmt->bind_param('sss', $open, $write, $usname);
$stmt->execute();
}
?>
<script>
jQuery(document).ready(function($) {
let lastActivity = <?php echo time(); ?> ; // storing last activity of user
let now = <?php echo time(); ?> ;
let logoutAfter = 10;
let userName = "<?php echo $_SESSION['user_name']; ?>";
let timer = setInterval(function() {
now++;
let delta = now - lastActivity;
console.log(delta);
if (delta > logoutAfter) {
clearInterval(timer);
//DO AJAX REQUEST TO close.php
$.ajax({
url: "/abc/mno.php",
type: 'GET',
data: {
action: 'logout',
user_name: userName
}, // Line A
success: function(data) {
console.log(data); // Line B
},
error: function(jqXHR, textStatus, errorThrown) {
alert(textStatus);
}
});
}
}, 1000);
});
</script>
最后的几点说明:
- 将 PHP、HTML 和 JS 完全组合在一个文件中是一种不好的做法。
- 您的代码的某些部分不容易重现,我不得不从上下文中猜测(例如,我猜想会话已经设置,使用了 jQuery 但没有
<script src="...jquery.js">
,有一个 DB 查询但没有单独的 SQL 导入来尝试它迅速地)。请在您的下一个问题中阅读并应用如何创建一个最小的、可重现的示例中的知识,以便更多的人能够或愿意帮助您。
推荐阅读
- python - Pandas - AttributeError:“NoneType”对象没有属性“管道”
- linux - zip 在终端中有效,但在脚本中无效?
- function - 如何修复程序集中的“未处理的异常”错误?
- python - 从嵌套字典中删除所有出现的值
- kubernetes - Kubernetes 上的 IBM 文件存储卡在“待处理”
- regex - 前瞻密码的正则表达式
- url - 在 URL 中使用表情符号和星号 * 是否安全?
- mysql - 如何避免 MySQL 中的特定字符
- javascript - 即使第一个函数调用第二个函数也没有按正确的顺序触发
- reactjs - 在打字稿中将 useState 作为道具传递