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 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 基于卷积神经网络的声纹识别
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图
  • ¥15 写一个方法checkPerson,入参实体类Person,出参布尔值
  • ¥15 我想咨询一下路面纹理三维点云数据处理的一些问题,上传的坐标文件里是怎么对无序点进行编号的,以及xy坐标在处理的时候是进行整体模型分片处理的吗
  • ¥15 一直显示正在等待HID—ISP