【问题标题】:xmlhttp request not workingxmlhttprequest 不工作
【发布时间】:2010-07-01 09:14:01
【问题描述】:

我正在尝试构建一个基本的聊天站点,并且有四个文件:chat.html、scripts.html、load.php 和 send.php。

他们在这里:

聊天.html:

<html>
    <head>
        <title>Josh's Python Chat Website</title>
        <script type="text/javascript" src="chatscripts.js">
        </script>
    </head>
    <body>
        <div id="divUsername" style="
            position: absolute;
            padding: 0px;
            margin: 0px;
            top: 10px; 
            left: 10px; 
            height: 26px; 
            width: 400px;">
            Username: <input type="text" id="username" />
        </div>

        <div id="display" style="
            border-style: solid;
            border-width: 1px;
            overflow:auto; 
            position: absolute;
            padding: 0px;
            margin: 0px;
            top: 46px;
            left: 10px;
            height:400px; 
            width:400px;">
        </div>

        <div id="divLineInput" style="
            position: absolute;
            padding: 0px;
            margin: 0px;
            top: 456px;
            left: 10px;
            height: 26px;
            width: 400px;">
            <input type="text" id="line" size="50" onkeydown="if(event.keyCode==13) send()" />
            <input type="button" id="sendbutton" value="Send" onclick="send()" />
        </div>
    </body>
</html>

scripts.js:

function load(){
    var xmlhttp = new XMLHttpRequest();
    var params="";
    xmlhttp.open("GET", "load.php", true);
    // xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.onreadystatechange = function() {
        if(xmlhttp.readyState==4 && xmlhttp.status==200){
            var display = document.getElementById("display");           
            display.innerHTML = xmlhttp.responseText;
            display.scrollTop = display.scrollHeight;
        }
    }
    xmlhttp.send(params);
}

function send(){
    var xmlhttp = new XMLHttpRequest();
    var url="send.php";
    var d = new Date();
    var username = document.getElementById("username");

    if (username.value==null || username.value==""){
        alert("Please enter a username.");
        username.focus();
        return false;
    }

    var line = document.getElementById("line");
    var params= "time=" + d.getTime().toString() + "&user=" + username.value + "&line=" + line.value;
    xmlhttp.open("POST", url, true);
    xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlhttp.onreadystatechange = function(){}
    xmlhttp.send(params);

    document.getElementById("line").value = "";

    load();
    line.focus();
}

load();
setInterval("load()", 3000);

加载.php:

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);

$dbhost = "localhost";
$dbuser = "root";
$dbpass = "password";
$dbname = "website";

$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ("Error connecting to database");
mysql_select_db($dbname);

$query = "select * from chat";
$result = mysql_query($query);
$num = mysql_numrows($result);

$response = "";
$i = 0;
while($i < $num){
    $response .= "<p>" . mysql_result($result, $i, "user") . ": " . mysql_result($result, $i, "line") . "</p>";
    $i++;
}

mysql_free_result($result);
mysql_close($conn);

echo $response;
?>

最后,send.php:

<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);

$dbhost = "localhost";
$dbuser = "root";
$dbpass = "password";
$dbname = "website";

$conn = mysql_connect($dbhost, $dbuser, $dbpass) or die ("Error connecting to database");
mysql_select_db($dbname);

$query = "insert into chat (time, user, line) values ('" . $_GET['time'] . "', '" . $_GET['user'] . "', '" . $_GET['line'] . "')";
mysql_query($query);
mysql_close($conn);
?>

该站点加载我使用命令行客户端插入到 mysql 数据库中的聊天条目。 send.php 也可以,因为当我调用

localhost/send.php?time=12345&user=Herrturtur&line=HelloWorld

在我浏览器的地址栏中,“Herrturtur: HelloWorld”会在重新加载时显示在聊天窗口中。

创建数据库的脚本如下:

create table chat (time INT(16), user VARCHAR(256), line TEXT);

所以我认为它一定是 scripts.js 中的 send() 函数。将请求类型更改为 GET 后,我没有比这种方式更多的运气,所以我发布了这个版本。我的代码有什么问题?

【问题讨论】:

  • 我可能是平庸的,但是使用任何常见的 AJAX 库在 js 中发出请求都会为您节省很多头发。能调试 XMLHttpRequest 的人不多。
  • 你能推荐一个好的吗?
  • 我确实使用jquery,所以不能告诉别人。这是基本的 ajax 文档。稍微滚动一下,就会找到示例。

标签: javascript xmlhttprequest chat


【解决方案1】:

直接调用 XMLHttpRequest 就像使用 blink 标签:没有什么好处。

使用图书馆!

  • 你想做很多Javascript吗?然后尝试使用更大的库,例如 JQuery 或 YUI。
  • 如果您只想要最低限度,您可以使用 mooTools 或其他小型库。
  • Google 通过其 CDN(内容交付网络)提供最受欢迎的库。见http://code.google.com/apis/ajaxlibs/

【讨论】:

  • 如果您决定需要使用库的一些功能,例如 DOM 操作或视觉效果,请使用库。仅仅因为你需要 10 行代码的帮助就加载一个 30KB 的库,这太过分了。如果您想要轻量级和快速的东西,没有什么可以替代编写自己的代码。另外,您可能会了解浏览器的工作原理。
【解决方案2】:

事件被触发了吗?开始在其中放置一些 console.logs 并诊断您的函数是否被调用。

edit -- 等等,你的脚本名称与标签中的内容不匹配。

【讨论】:

  • 脚本名称与标签中的内容不匹配?我仔细检查了两个标签中的脚本名称是“send()”,而在 scripts.js 中是“send()”。我去查一下console.logs是什么意思。
【解决方案3】:

几件事:

  1. 如果您的 PHP 使用 $_POST,那么指向该脚本的 AJAX open() 也应该是 POST。同样,如果你的 PHP 使用$_GET,你的open() 应该使用GET。
  2. 使用浏览器控制台检查params 中实际设置的内容。这个字符串应该能够在 GET 请求中放在 URL 的末尾[编辑:我的意思是你应该能够将它放在浏览器中地址的末尾]并且仍然可以工作。如果不是,请确保进入 params 的每个元素都经过 URL 编码。
  3. 我知道这不是问题的一部分,但就像现在一样,您的数据库查询很容易受到 SQL 注入攻击。确保您转义将进入数据库的每个值。此外,如果您可以将 time 存储为数字而不是字符串,您的查询将大大加快。当您只有几百或几千条记录时,使用字符串的性能成本在开发过程中永远不会出现,但当您的数据库开始填满时就会出现。

我不明白为什么这么多人反对推出你自己的 XHR 请求。使用库可以解开早期构建 AJAX 应用程序的许多谜团,但如果您使用了错误的方法(POST 而不是 GET),它对您无济于事,而且调试实际上会更加困难,因为您需要深入挖掘通过 lot 的代码来查看失败的地方。它实际上甚至不是很困难,并且自己动手可以帮助您了解请求的生命周期。下面是一个常见的跨浏览器 sn-p。这将使XMLHttpRequest 即使在早期的 IE 浏览器中也可用:

if (typeof XMLHttpRequest === "undefined")
  XMLHttpRequest = function () {
    try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
      catch (e) {}
    try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
      catch (e) {}
    try { return new ActiveXObject("Msxml2.XMLHTTP"); }
      catch (e) {}
    //Microsoft.XMLHTTP points to Msxml2.XMLHTTP.3.0 and is redundant
    throw new Error("This browser does not support XMLHttpRequest.");
  };

【讨论】:

  • 我在 send.php 中修复了将 GET 更改为 POST,但仍然没有运气。
  • 两件事: 1. 如果您使用的是带有控制台的浏览器(带有 Firebug 插件的 Firefox、Chrome 或打开了开发者工具栏的 IE8/Safari),请添加此调试代码在您的xmlhttp.send():console.log(params,url); 上方。将您在控制台中看到的内容发回此处。不要在您的生产版本中部署此代码。它仅用于调试。 2. 如果请求在服务器端失败,这些失败将在您的日志中。您还可以通过以下方式检查错误:` xmlhttp.onreadystatechange = function(){alert(xmlhttp.readyState+', '+xmlhttp.statusText);}` 你看到了什么警报?
  • 对于1:输出为time=1277976523479&user=Joshua&line=Test send.php
  • 对于 2:我得到“2,OK”,“3,OK”和“4,OK”。
  • 啊。我还刚刚注意到您的time 列是INT(16),但您的更新查询正在尝试插入一个字符串。删除time 值周围的单引号:$query = "insert into chat (time, user, line) values (" . $_POST['time'] . ", '" . $_POST['user'] . "', '" . $_POST['line'] . "')"; 还有一件事,如果您使用 Firefox+Firebug 或 Safari/Chrome,您可以在“Net 控制台”中查看服务器响应。它是调试 AJAX 应用程序的关键工具。如果你使用 IE,你应该下载并使用 Fiddler2。这是一个非常复杂的工具,但却是其中最好的。得到它! `
猜你喜欢
  • 2014-07-27
  • 1970-01-01
  • 2018-05-28
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多