更换重装页面

时间:2016-03-09 15:00:14

标签: php html ajax

我正在使用php开发一个简单的聊天应用程序。 我使用ajax将消息插入数据库,并且每5秒钟后我重新加载页面,这样如果有任何新消息到达它会刷新,用户将能够看到新消息,但这不是一个好方法。我想要一个解决方案,以便如果有任何新消息到达,用户可以看到没有重新加载页面后每5秒。 我用过的javascript代码是:

            $(document).ready(function() {
            debugger;
    var percentageToScroll = 100;
    var height = $('.panel-body').innerHeight();
    var scrollAmount = height;
     var overheight = jQuery(document).height() - jQuery(window).height();
jQuery(".divcls").animate({scrollTop: scrollAmount}, 900);    
});
setTimeout(function(){
   window.location.reload(1);
}, 5000);

        function checkMsg()
        {
            //alert("Enter");
            var message = document.getElementById("msg").value;
            //alert(message);
            if (message === "")
            {
                alert("Please Enter Message");
            } else
            {
                submitChat(message);
            }

        }
        ;
        function submitChat(message)
        {
            // alert("Enter");
            var msg = message;
            var xmlhttp = new XMLHttpRequest();

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                    document.getElementById('msg').innerHTML = "";
                    location.reload();

                }
            }
            xmlhttp.open('GET', 'insert.php?msg=' + msg, true);
            xmlhttp.send();

        };

主页聊天框的代码段是:

     <div style="overflow: scroll ;max-height: 650px; width: 100%;" class="divcls">
            <div class="panel-body">

<ul class="media-list">
    <?php
    include './connect.php';
                                        $sql = "select * from chatlog";
                                        $result = mysqli_query($con,$sql);
                                        while ($row = mysqli_fetch_array($result)) {
                                            ?>
                                    <li class="media">

                                        <div class="media-body">

                                            <div class="media">
                                                <a class="pull-left" href="#">
                                                    <img class="media-object img-circle " src="assets/img/user.png" />
                                                </a>
                                                <div class="media-body">
                                                    <span id="chatData"><?php echo $row["Msg"]; ?></span>
                                                    <br/>
                                                   <small class="text-muted"><?php echo $row["UserName"]; ?> | 23rd June at 5:00pm</small>
                                                    <hr />
                                                </div>
                                            </div>

                                        </div>
                                    </li>
                                    <?php
                                        }
                                        ?>
                                </ul>
                </div>
            </div>

插入页面:

    <?php

require("connect.php");
$msg=$_GET['msg'];
$result=mysqli_query($con, "INSERT INTO chatlog(UserName, Msg) VALUES('admin','$msg')");

    header("location:index.php");
?>

1 个答案:

答案 0 :(得分:0)

警告:这个答案很长。所以,拿起你的咖啡做好准备。

首先,我想谈谈这段代码:

<?php

require("connect.php");
$msg=$_GET['msg'];
$result=mysqli_query($con, "INSERT INTO chatlog(UserName, Msg) VALUES('admin','$msg')");

header("location:index.php");
?>

请告诉我这不是您的源代码的直接复制和粘贴?如果是这样,您非常需要编辑它以防止SQL注入。为此,请尝试使用以下内容:

<?php

require("connect.php");
$msg= $con->real_escape_string($_GET['msg']);
$result=mysqli_query($con, "INSERT INTO chatlog(UserName, Msg) VALUES('admin','$msg')");

header("location:index.php");
?>

您可能还想考虑使用预准备语句,但real_escape_string()至少会通过转义可能有害的消息来阻止注入。考虑阅读this SO Question以获取有关防止SQL注入攻击的最佳实践的更多信息。作为附加安全说明,您还应该考虑应用过滤器来防止XSS。

无论如何,我知道这不是你问题的主题,但是当我看到它们时,我总是倾向于提到这些缺陷。 (修复它们会保护您,您的网站和您的用户。)除了您的实际问题之外!

我见过很多“聊天框”实现,其中大多数都是以两种方式之一工作的:

  1. 网页定期查询/轮询后端脚本,该脚本返回聊天框中消息的格式正确的HTML;或
  2. 网页会跟踪所有带有ID的消息(有时使用localStoragesessionStorage),网页使用上次收到的消息的ID查询后端脚本,后端脚本返回任何消息自该ID以来已收到(任何比上次收到的消息更新的消息)。
  3. 就个人而言,我是第二种方法的粉丝,但有时第一种方法更容易实现。此外,要使用第二种方法,您的数据库需要在聊天记录条目中存储自动递增的唯一标识符。

    方法一实施

    因为第二种方法可能会因为你的方式而有点复杂,所以我会写一个第一种方法的例子。

    以下是我将被轮询的后端PHP代码(我们称之为get_chat.php):

    <?php
    // File: backend/get_chat.php
    require_once('./connect.php');
    $sql = "select * from chatlog";
    $result = mysqli_query($con,$sql);
    while ($row = mysqli_fetch_array($result)) {
    
    ?>
    <li class="media">
        <div class="media-body">
    
            <div class="media">
                <a class="pull-left" href="#">
                    <img class="media-object img-circle " src="assets/img/user.png" />
                </a>
                <div class="media-body">
                    <span id="chatData"><?php echo $row["Msg"]; ?></span>
                    <br/>
                   <small class="text-muted"><?php echo $row["UserName"]; ?> | 23rd June at 5:00pm</small>
                    <hr />
                </div>
            </div>
    
        </div>
    </li>
    <?php
    
    } /* End While Loop */
    
    ?>
    

    注意此代码将生成id="chatData"的多个跨度。我已经离开了这样的代码,因为这也是你的原始代码所做的。但是,您不应该重复ID。我会在你认为合适的情况下由你来解决。

    接下来,我们需要Javascript与此代码进行交互:

    // We will want to set an initial timeout to start the refreshChat() 'cycle' (so to speak)
    var timerId = setTimeout(function(){
                                refreshChat();
                            },
                    3000
                ); /* End setTimeout(); */
    
    function refreshChat(){
        var xmlhttp = new XMLHttpRequest();
    
        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState === 4) { // Request finished
    
                // Check if the status code indicates success
                if(xmlhttp.status === 200){
                    var chatbox = document.getElementById('chatBox');
                    chatbox.innerHTML = xmlhttp.responseText; // Set the inner-chatbox body
                } // Else, something went wrong.
    
                // Regardless of whether or not the request succeeded, the request has finished
                // so we should now set up a new timeout to automatically refresh the window again.
    
                // First, we'll try to clear the timeout so we don't potentially end up with two timeouts (which, in theory, would only happen if there is an error):
                clearTimeout(timerId);
    
                // Now we'll just go ahead and set the new timeout:
                timerId = setTimeout(function(){
                                            refreshChat();
                                        },
                                    3000
                                ); /* End setTimeout(); */
            }
        } // End readyStateChange function
    
        var cacheBreaker = new Date().getTime(); // Current time to prevent caching
        xmlhttp.open('GET', 'backend/get_chat.php?anticache=' + cacheBreaker, true);
        xmlhttp.send();
    };
    

    好的,现在我们有Javascript调用PHP脚本,然后接收所有最新聊天消息的HTML。但是,我们还没有完成。现在我们需要指定HTML的去向。在Javascript中我们说document.getElementById('chatBox');,但我们目前实际上没有任何ID chatBox 的元素。

    要解决此问题,并将重新加载的HTML放到正确的位置,我们需要做的就是将<ul class="media-list">更改为<ul id="chatBox" class="media-list">。现在,Javascript将知道我们将返回的HTML插入哪个元素,并且它将能够更新消息列表。

    但我们还没有完成。现在我们需要对submitChat(message)函数进行实际操作。我们不希望它重新加载页面,对吗?我们可能不希望用户提交消息,然后在出现之前必须等待3秒钟,因此,我们应该用以下内容替换submitChat()

    function submitChat(message){
        // alert("Enter");
        var msg = message;
        var xmlhttp = new XMLHttpRequest();
    
        xmlhttp.onreadystatechange = function () {
            // Handle this the same we handle refreshing the chat:
            if (xmlhttp.readyState === 4) { // Request finished
    
                // Check if the status code indicates success
                if(xmlhttp.status === 200){
                    var chatbox = document.getElementById('chatBox');
                    chatbox.innerHTML = xmlhttp.responseText; // Set the inner-chatbox body
                } // Else, something went wrong.
    
                // First, we'll try to clear the timeout so we don't prematurely run refreshChat():
                clearTimeout(timerId);
    
                // Now we'll just go ahead and set the new timeout:
                timerId = setTimeout(function(){
                                            refreshChat();
                                        },
                                    3000
                                ); /* End setTimeout(); */
            }
        }
        xmlhttp.open('GET', 'insert.php?msg=' + msg, true);
        xmlhttp.send();
    
    };
    

    现在,要使用这个新的Javascript,我们需要稍微修改我们的insert.php代码:

    <?php
    
    require("connect.php");
    $msg= $con->real_escape_string($_GET['msg']);
    $result=mysqli_query($con, "INSERT INTO chatlog(UserName, Msg) VALUES('admin','$msg')");
    
    // And now we'll return the newest messages in the database:
    include_once('get_chat.php');
    ?>
    

    就是这样。我们现在有一个聊天框,它会自动刷新自己,允许某人发布消息,并且具有针对SQL注入攻击的基本保护。

    同样,我建议您考虑添加XSS保护,您可能需要考虑使用上述第二种方法来编写它。但是,方法二在这里实现起来太长且太复杂,而且XSS保护不在本问题的范围内,所以我将把这些留给你。

    注意我尚未在此处测试代码,因此可能包含一些错误。我试图通读所有代码来仔细检查它,但我确信我错过了一些小错误。尽管如此,这应该让你开始走正确的道路。如果某些事情没有意义,请不要犹豫,发表评论并询问。