如何在Javascript中创建、合并和销毁xmlhttprequest对象 我的背景是在传统编译的面向对象语言中,比如C++和.NET编程,现在我正在为一个新项目涉足一点JavaScript。我曾涉猎过AJAX,但在浏览器如何管理对象方面遇到了一个令人困惑的问题

如何在Javascript中创建、合并和销毁xmlhttprequest对象 我的背景是在传统编译的面向对象语言中,比如C++和.NET编程,现在我正在为一个新项目涉足一点JavaScript。我曾涉猎过AJAX,但在浏览器如何管理对象方面遇到了一个令人困惑的问题,javascript,html,ajax,xmlhttprequest,Javascript,Html,Ajax,Xmlhttprequest,[编辑#2]-活动内容脚本的更改 我有一个带有三个按钮的练习页面,每个按钮都使用XMLHttpRequest对象更新: 按钮1使用slowtime.php中的文本内容更新TextArea1 按钮2使用slowtime.php中的文本内容更新TextArea2 按钮3使用fasttime.php中的文本内容更新TextArea3 其中slowtime.php和fasttime.php是简单的脚本,它们返回一个带有两个时间戳的text/HTML页面:一个是在页面加载时,一个是在一段时间后 每次单击一

[编辑#2]-活动内容脚本的更改

我有一个带有三个按钮的练习页面,每个按钮都使用
XMLHttpRequest
对象更新

  • 按钮1使用slowtime.php中的文本内容更新TextArea1
  • 按钮2使用slowtime.php中的文本内容更新TextArea2
  • 按钮3使用fasttime.php中的文本内容更新TextArea3
  • 其中slowtime.php和fasttime.php是简单的脚本,它们返回一个带有两个时间戳的text/HTML页面:一个是在页面加载时,一个是在一段时间后

    每次单击一个按钮时,每个按钮都能正常工作。如果在第一个请求完成之前单击按钮2,然后单击按钮3,则更新仍能按预期工作

    如果在第一个请求完成之前单击按钮1,然后单击按钮2,则TextArea1和TextArea2会收到正确的值;但是,
    onreadystatechange
    事件调用同时发生,即第一个响应延迟,只有在第二个响应到达时才进行处理

    示例代码

    网站

    <!DOCTYPE html>
    <html>
    <head>
    <script>
    function loadXMLDoc(url,target)
    {
    var xmlhttp;
    xmlhttp=new XMLHttpRequest();
    
    xmlhttp.onreadystatechange=function()
      {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        document.getElementById(target).value=xmlhttp.responseText;
        }
      }
    xmlhttp.open("POST",url,true);
    xmlhttp.send();
    }
    </script>
    </head>
    
    <body>
    <form>
    
    <input type="button" value="Button 1" onClick="loadXMLDoc('slowtime.php','TextArea1')"/>
    <input type="button" value="Button 2" onClick="loadXMLDoc('slowtime.php','TextArea2')"/>
    <input type="button" value="Button 3" onClick="loadXMLDoc('fasttime.php','TextArea3')"/>
    
    <div><textarea id="TextArea1"></textarea></div>
    <div><textarea id="TextArea2"></textarea></div>
    <div><textarea id="TextArea3"></textarea></div>
    
    </form>
    </body>
    </html>
    
    
    函数loadXMLDoc(url,目标)
    {
    var-xmlhttp;
    xmlhttp=新的XMLHttpRequest();
    xmlhttp.onreadystatechange=函数()
    {
    if(xmlhttp.readyState==4&&xmlhttp.status==200)
    {
    document.getElementById(target.value=xmlhttp.responseText;
    }
    }
    open(“POST”,url,true);
    xmlhttp.send();
    }
    
    PHP代码(slowtime.PHP)

    
    
    问题[修订]

    浏览器如何管理
    XMLHttpRequest
    对象?按下按钮2和3表示每次按下都会实例化一个新对象,并且每个按钮都有独立的事件处理程序。如果对象超过了初始函数调用(因为它们的事件处理程序仍然存在),那么它们何时从内存中清除/销毁


    如果
    XMLHttpRequests
    是独立的对象,那么向同一URL发送第二个请求如何影响第一个请求的响应时间?这可能是服务器端问题吗?

    除非对对象显式调用delete,否则永远不会删除XMLHttpRequest的上下文。在本例中:xmlhttp。如果你想让你的应用程序运行得更精简、更干净,你真的应该以某种方式跟踪这个var并将其清理干净。Javascript最初是为网页设计的,因此,除非您自己阻止它,否则它往往会让事情失控

    否则,一旦对象不再可由任何其他函数使用或有任何剩余的回调,浏览器的垃圾收集器就可能删除该对象

    至于您同时发生事件的问题,我自己无法重现该问题,这让我相信您的php配置存在问题。您的服务器是否可能不允许同时运行多个脚本

    以下是您在我的服务器上的示例,其中有一些细微的更改:
    这是一个浏览器问题

    • Chrome 23和26的表现就是这样
    • 歌剧12没有
    • IE 9没有
    • Firefox17没有
    如果您使URL唯一,例如
    slowtime.php?1
    slowtime.php?2
    ,那么chrome不再以这种方式运行


    顺便说一句,在我的测试中,chrome用相同的值更新了两个文本区域——第一次请求的值。它们都在第一个请求完成时更新,而不是在第二个请求完成时更新。这肯定是一个错误,因为它完全错了。我通过Web服务器日志验证了第二个请求从未发送。

    xmlhttp.onreadystatechange
    函数中,您是否应该使用
    this.responseText
    而不是
    xmlhttp.responseText
    ?@JoshuaD.Boyd,因为
    xmlhttp
    变量位于
    loadXMLDoc
    内的本地范围内,所以它不应该做任何其他事情函数也起作用,并产生相同的结果behavior@nicholas你能提供slowrand.php和fastrand.php的源代码吗?@seliopou:你让我发现了服务器端代码的一个主要问题。对于诊断,slowrand正在打开并写入文件。第二个slowrand调用试图打开一个锁定的文件,因此出现了错误——长话短说,使用不同的php代码来编写时间戳,我得到了不同的结果。请求没有合并,但是它们的时间安排混乱了。感谢您将代码发布到不同的测试服务器上。当我在Chrome或Safari中测试你的站点时,我得到了与上面rambo相同的结果——两个文本区域得到相同的值。与此同时,Firefox、IE9和Silk没有。您的页面在Maxthon mobile browser中根本无法工作。过了很长时间,我会接受这个答案,因为它直接处理请求的上下文。这是一个有趣的讨论,至少目前来看,web开发/浏览器等在执行脚本的方式上仍然不统一。当我在kokorohakai的服务器上使用Chrome或Safari进行测试时,我看到了与您相同的结果-两个文本区域获得相同的值,并且与第一个请求同步。同时,在我的测试服务器(localhost)上,我得到两个不同的值,用第二个值计时。这让我相信答案确实非常复杂,而且基于浏览器和服务器行为。@nicholas您的本地服务器日志是否显示了两个请求?尽管如此,chrome在我的测试中只发送了一个请求这一事实表明它有一个bug(或者一个奇怪的特性)。
    <?php
         echo date('h:i:s') . "\n";
         sleep(5);
         echo date('h:i:s') . "\n";
    ?>