douzi8127 2011-11-25 17:43
浏览 40
已采纳

是否可以使用XMLHttpRequest评估JavaScript代码

I'm trying to use this AJAX request to call a file with some PHP which is working ok and some JavaScript which is not. any ideas?

function showpart2(){
    if(window.XMLHttpRequest){
        xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET","atuamae.org/parte2-encomendar.php",false);
        xmlhttp.send(null);
    }

    document.getElementById('part2').innerHTML = xmlhttp.responseText;
    eval(xmlhttp.responseText.getElementById('part2').innerHTML)

    setTimeout('showpart2()',15000);

}

showpart2();
  • 写回答

4条回答 默认 最新

  • doujiongqin0687 2011-11-26 10:17
    关注

    One big problem with the sample code is that making XMLHttpRequest.send synchronous means all JS execution must pause while waiting for the request to be received. There's no reason not to use an asynchronous call.

    Asynchronous calls can improve responsiveness, but what they don't give you is coordination, which means a task won't run until the data it needs is ready. The standard way of coordinating asynchronous code is to pass to the asynchronous function a function that, when executed, performs the rest of the computation that relies on the data. This function has the technical name "continuation", which is simply a function that represents the rest of the computation from a given point forward. That is, turn:

    f1();
    f2();
    async();
    f3();
    f4();
    

    into:

    f1();
    f2();
    async(function() {
        f3();
        f4();
    });
    

    Because you're passing around a continuation, this is known as "continuation passing style". XMLHttpRequest is a special case in that rather than passing a function to the asynchronous function, you set it as a listener for the readystatechange event on the XHR object. That is, you assign the continuation to xmlhttp.onreadystatechange.

    There are a few more improvements to make. First, add error detection. The status property of the XHR instance holds the HTTP status, which you can use to check for errors.

    As a number of others have mentioned, eval can be problematic and should be avoided when there's another option. For one thing, you have to make sure the string comes from a trusted source. The particular problem with eval here is that the script is evaluated in the same context as the call to eval. If the eval happens inside a function, anything defined by the script isn't visible outside the function. If your script doesn't need to define anything (and will never need to define anything; always consider the future of your code), you can use eval. Otherwise, dynamically create a script element with the script as content and add it to the document; you can define a function that does this (see globaleval in the sample below).

    xmlhttp is a global variable, which is bad. Instead, declare it as a local variable.

    Rather than setTimeout, which is for one-shot calls, use setInterval, which calls the passed function periodically. Note that both setTimeout and setInterval may take longer than the given delay to run, though that shouldn't be an issue here.

    (function () {
        // keep variable from polluting global namespace
        var showpart2Interval = 0,
            scriptElt = {parentNode: {removeChild: function() {}}};
    
        function globaleval(script) {
            scriptElt.parentNode.removeChild(scriptElt);
            scriptElt = document.createElement('script');
            scriptElt.type = 'text/javascript'
            scriptElt.appendChild(document.createTextNode(script));
            document.body.appendChild(scriptElt);
        }
    
        function showpart2(){
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET","atuamae.org/parte2-encomendar.php",false);
            xmlhttp.onreadystatechange = function() {
                if (xmlhttp.readyState == 4) {
                    if (200 <= xmlhttp.status && xmlhttp.status < 300) {
                        globaleval(xmlhttp.responseText);
                    } else {
                        // HTTP error
                        ...
                    }
                }
            }
            xmlhttp.send(null);
        }
    
        function startShowpart2() {
            if (window.XMLHttpRequest && !showpart2Interval) {
                showpart2();
                showpart2Interval = setInterval(showpart2, 15000);
            }
        }
        function stopShowpart2() {
            clearInterval(showpart2Interval);
            showpart2Interval = 0;
        }
    
        window.startShowpart2 = startShowpart2;
        window.stopShowpart2 = stopShowpart2;
    })();
    
    startShowpart2();
    

    If you don't care about implementing all of this yourself, have jQuery do the heavy lifting. It's good to know how to do things yourself, but (for production code) using standard libraries with standard interfaces speeds up development in a number of ways.

    See also

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 MATLAB怎么通过柱坐标变换画开口是圆形的旋转抛物面?
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题
  • ¥15 Visual Studio问题
  • ¥20 求一个html代码,有偿