【问题标题】:Changing website content dynamically depending on MySQL database value根据 MySQL 数据库值动态更改网站内容
【发布时间】:2013-05-20 17:59:12
【问题描述】:

我想根据一个值动态更改我的网站。我从我的 MySQL 数据库中检索数据,并希望更改尽可能接近实时。我有一些代码在某种程度上可以执行我想要的操作,但是值的更新似乎失败了,起初它可以工作,然后在几次调用之后,它似乎只是在两个值之间随机切换。

我有三个 php 页面,一个从数据库中检索一个值(database.php),另一个根据数据库值生成响应(response1.php 和 response2.php)。我不认为这些页面是问题的一部分,因为我已经检查过它们是否返回值并且它们返回了我想要的内容。项目的第二部分(可能会失败)是我的主要 html 页面(如下)。我不确定我是否选择了解决问题的最佳技术,或者是否有更好的方法来解决问题。

<html>
<head>
    <script type="text/javascript">
        var databaseanswer, xmlhttp;

        function databasecheck() {
            xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", "database.php", true);
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    databaseanswer = xmlhttp.responseText;
                    document.getElementById("database").innerHTML = xmlhttp.responseText;
                }
            };
            xmlhttp.send();
        }

        function response() {
            if (databaseanswer == "No Tag") {
                xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", "response1.php", true);
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("response").innerHTML = xmlhttp.responseText;
                    }
                };
                xmlhttp.send();
            }
            else {
                xmlhttp = new XMLHttpRequest();
                xmlhttp.open("GET", "response2.php", true);
                xmlhttp.onreadystatechange = function() {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                        document.getElementById("response").innerHTML = xmlhttp.responseText;
                    }
                };
                xmlhttp.send();
            }
        }

        setInterval(databasecheck, 1800);
        setInterval(response, 2000);

    </script>
</head>
<body>
    <p> this is a test site </p>
    <p> response from server: </p>
    <div id="response">
    </div>
    <p> answer from database: </p>
    <div id="database">
    </div>
</body>
</html>

好的,这是我编辑的代码:

<html>
<head>
<script>

function database(){
  var xmlhttp = new XMLHttpRequest();

  xmlhttp.open("GET","responsedatabase.php",false);
  xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
      {
        document.getElementById("database").innerHTML=xmlhttp.responseText;
      }
      }
  xmlhttp.send();
}

setInterval(database,1000);

</script>
</head>
<body>
<p>answer from database: </p><div id="database"></div>
</body>
</html>

【问题讨论】:

  • 您应该考虑使用jQuery's AJAX 功能:api.jquery.com/jQuery.ajax
  • if (databaseanswer == "No Tag") { 毫无意义,或者其他什么
  • 基本上“无标签”是我数据库中的默认值。

标签: javascript mysql ajax xmlhttprequest


【解决方案1】:

问题是您正在发送多个异步请求并且请求未序列化。请记住,您无法控制请求的响应时间。此外,随着时间的推移,responsedatabasecheck 调用之间的时间量不断增加。例如。最初,databasecheck 将在 1.8 秒后执行,response 将在 2 秒后执行;差异为 200 毫秒。第二次,databasecheck会在3.6秒后执行,response会在4秒后执行;差异为 400 毫秒。

除此之外,请求的响应时间不受您的控制。您提出的第一个请求不一定是第一个完成的请求。也就是说,即使您序列化对databasecheckresponse 函数的调用,如果您不序列化XHR 调用,您将得到明显随机的结果。也就是说,假设databasecheck返回了x,而你发送了一个response1.php的请求;当它仍在进行中时,假设第二个对databasecheck 的请求返回了y,并且对response2.php 发起了另一个请求。现在,根据对 response1.phpresponse2.php 的请求完成的顺序,您可能会看到正确或错误的结果。而且,在这种情况下,对database.php 的另一个请求可能已完成,您将再次看到一些不同的结果。这就是结果明显随机的原因。

您需要做的是序列化对databasecheckresponse 函数的调用。也就是说,只有在对database.php 的请求完成后,才发起对response 的调用。现在,您需要确保请求之间也没有竞争条件。这有点麻烦,您可能会丢失实时行为。

更好的方法是将调用database.php 的结果与调用response1.phpresponse2.php 的结果结合起来。即,将逻辑移至服务器端。将代码放在response1.phpresponse2.php 中返回值的函数中。假设这些函数被命名为response1response2。在您的database.php。根据数据库值调用这些函数中的任何一个。将结果与数据库值一起放入关联数组中,并将响应作为 JSON 格式的字符串返回。这样,您将减少一个请求,并且不会出现同步问题。

更新后

您需要在更新后的代码中执行以下操作:

var requestInProgress = false;
function database() {
    if(requestInProgress) {
        return;
    }
    var xmlhttp = new XMLHttpRequest();

    xmlhttp.open("GET","responsedatabase.php",false);
    xmlhttp.onreadystatechange=function() {
        if (xmlhttp.readyState == 4) {
            requestInProgress = false;
            if(xmlhttp.status==200) {
                document.getElementById("database").innerHTML=xmlhttp.responseText;
            }
        }
    }
    requestInProgress = true; 
    xmlhttp.send();
}

您也可以减少setInterval 中的持续时间,以确保在上一个请求的结束和新请求的开始之间没有太多延迟。

【讨论】:

  • 好的,所以我已将我的 response1.php 和 response2.php 合并到我的 database.php 中(从而在该文件中选择响应)。然后我为 database.php 执行 XMLHttpRequest,但这给了我同样的同步问题。
  • 发布你的新 JS 代码。不应该有更多的竞争条件,因为应该只有一个函数调用和一个请求。此外,请勿在前一个请求正在进行时发出新请求。
  • 我已将编辑后的代码添加到我的原始问题中。谢谢。
  • 好的,这似乎工作得更好,但它远非实时发生 - 我可以做些什么来改进它,或者我是否受到使用这种技术的限制? (我应该考虑另一种方式吗?你有什么建议吗)。
  • 实际上,错误的值似乎仍然存在一些问题(它仍然会输出“No Tag”,即使那不是数据库中的值。我认为它可能是PHP缓存或类似的东西?我添加了 - header("Cache-Control: no-cache, must-revalidate"); header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); 到我的 php文件(但这不起作用)。
猜你喜欢
  • 2013-02-11
  • 2017-10-23
  • 2012-10-27
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
  • 2019-01-30
  • 2016-04-01
  • 1970-01-01
相关资源
最近更新 更多