微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单击按钮X秒钟不活动后如何注销?

如何解决单击按钮X秒钟不活动后如何注销?

我正在一个简单的项目中,我有一个具有多个用户登录系统,每个用户登录并将表单条目保存在文件中。我正在尝试建立会话超时,以便在闲置2分钟后可以注销我。

以上所有方法都可以正常工作。现在,我正在尝试建立此会话超时,以便它可以在闲置x分钟后将我注销,然后将我重定向login.PHP页。

这是我的index.PHP文件

<?PHP

declare(strict_types = 1);

// Start session.
session_start();

// Include helper functions.
require_once 'helpers.PHP';

// 2 mins in seconds
$inactive = 120; 

if(isset($_SESSION['timeout']) ) {
    $session_life = time() - $_SESSION['timeout'];
    if($session_life > $inactive)
    { 
        redirect('logout.PHP');
        return;
    }
}

$_SESSION['timeout'] = time();

// Redirect user to login page if not authenticated.
if (! check_auth()) {
    redirect('login.PHP');
    return;
}

?>
<!doctype html>
<html>
<head>
    <title>Home</title>
</head>
<body>
    <div>
        <h1>Website Title</h1> <a href="logout.PHP">logout</a> </div>
    <div>
        <p>Welcome back,<?= $_SESSION['user_id'] ?>!</p>
    </div>
    <form method="post">
        <input type="text" name="field1" />
        <input type="text" name="field2" />
        <input type="submit" name="submit" value="Save Data"> </form>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script>
    $(function() {
        $('form').submit(function(e) {
            e.preventDefault();
            $.post({
                url: 'save.PHP',data: $(this).serialize(),}).done(response => {
                response = JSON.parse(response);
                if(response.message) {
                    alert(response.message);
                }
            });
        });
    });
    </script>
</body>
</html>

这是我的save.PHP文件

<?PHP
declare(strict_types=1);
// Start session.
session_start();
// Include helper functions.
require_once 'helpers.PHP';

// 2 mins in seconds
$inactive = 120; 

if(isset($_SESSION['timeout']) ) {
    $session_life = time() - $_SESSION['timeout'];
    if($session_life > $inactive)
    { 
        redirect('logout.PHP');
        return;
    }
}

$_SESSION['timeout'] = time();

// Redirect user to login page if not authenticated.
if (! check_auth()) {
    redirect('login.PHP');
    return;
}

// save form entries in a file

这是我的helpers.PHP文件

<?PHP
declare(strict_types=1);

if (! function_exists('check_auth')) {
    function check_auth(): bool
    {
        return isset($_SESSION['user_id']);
    }
}

if (! function_exists('logout'))
{
    function logout()
    {
        if (isset($_SESSION['user_id'])) {
            $trace = json_decode(file_get_contents('current_user.txt'));

            if ((int) $trace->user_id === $_SESSION['user_id']) {
                $content = isset($trace->revoked_user_id)
                ? json_encode(['user_id' => $trace->revoked_user_id,'created_at' => (new DateTime('Now'))->format('Y-m-d H:i:s')])
                : '';
                file_put_contents('current_user.txt',$content);
            }

            unset($_SESSION['user_id']);
            unset($_SESSION['timeout']);
        }
    }
}

if (! function_exists('redirect')) {
    function redirect(string $url,int $status_code = 303): void
    {
        header('Location: ' . $url,true,$status_code);
        die();
    }
}

问题陈述

一旦在logout.PHPindex.PHP中空闲了2分钟的save.PHP文件,我将重定向到该文件。这是我要注意的-

  • 如果我在index.PHP页上,并且闲置了2分钟后,如果刷新浏览器,它将顺利退出我,没有任何问题,然后将我重定向login.PHP页。
  • 现在让我们说,如果我再次进入index.PHP页面,并且在闲置2分钟后如果单击Save Data按钮,则会在控制台上给我错误,但从技术上讲,它应该使我注销并将我重定向到login.PHP页面

下面是我在index.PHP页面上进行的Ajax调用-

<script>
$(function() {
    $('form').submit(function(e) {
        e.preventDefault();
        $.post({
            url: 'save.PHP',}).done(response => {
            response = JSON.parse(response);
            if(response.message) {
                alert(response.message);
            }
        });
    });
});
</script>

在闲置2分钟后,只要单击Save Data按钮,我的第2点就会收到json解析错误。并且response变量的值在html中是完整的login.PHP。我不确定为什么会这样。在它调用save.PHP之前,我们需要在jquery本身中检查会话验证吗?

解决方法

总而言之,您的问题是由save.php中的ajax请求重定向时引起的。

发生了什么事,redirect()请求被透明处理并且结果由jQuery.ajax().done()闭包处理,闭包试图为 JSON.parse(response);的HTML调用login.php 。 单击按钮时,您应该能够通过在浏览器中查看开发人员工具(通常为F12)来验证这一点。

解决此问题的一般方法是确定请求是否为XMLHttpRequest并发送不同的响应而不是重定向。

检测XMLHttpRequest

要确定请求是否来自jQuery.ajax(),请检查X-Requested-With请求标头。

isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest'

具有redirect属性的JSON响应

此方法在响应中返回redirect属性,并使用它从jQuery.ajax().done()闭包中重定向。

helpers.php

if (! function_exists('redirect')) {
    function redirect(string $url,int $status_code = 303): void
    {
        if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
            //do not redirect AJAX requests
            echo json_encode(['redirect' => $url]);
        } else {
            header('Location: ' . $url,true,$status_code);
        }
        die();
    }
}

index.php

$(function() {
    "use strict";
    $('form').submit(function(e) {
        e.preventDefault();
        $.post({
            url: 'save.php',data: $(this).serialize(),}).done(response => {
            response = JSON.parse(response);
            if (response.redirect) {
                //redirect user
                window.location.href = response.redirect; 
            }
            if (response.message) {
                alert(response.message);
            }
        });
    });
});

状态码响应

此方法返回200 Ok以外的状态代码,而不是重定向,并在jQuery.ajax()statusCode:方法中检查响应状态代码。

helpers.php

if (! function_exists('redirect')) {
    function redirect(string $url,int $status_code = 303): void
    {
        if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') {
            //do not redirect AJAX requests
            http_response_code(401); //Unauthorized - PHP 5.4+
            echo $url; //optionally output the url
        } else {
            header('Location: ' . $url,$status_code);
        }
        die();
    }
}

您可以在此处选择根据需要处理状态码。 对于最简单的方法,请检查fail() jqXhr对象状态代码并改为执行JavaScript重定向。

index.php

$(function() {
    "use strict";
    $('form').submit(function(e) {
        e.preventDefault();
        $.post({
            url: 'save.php',}).done(response => {
            response = JSON.parse(response);
            if (response.message) {
                alert(response.message);
            }
        }).fail(jqXhr => {
            if (jqXhr.status == 401) {
                //redirect to specified url in the response text
                window.location.href = jqXhr.responseText; 
               /* alternatively hard-code '/logout.php' */
            }
        });
    });
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。