Можно ли оценить код JavaScript с помощью XMLHttpRequest - PullRequest
1 голос
/ 25 ноября 2011

Я пытаюсь использовать этот AJAX-запрос для вызова файла с некоторым PHP, который работает нормально, и с некоторым JavaScript, который не работает.есть идеи?

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 ]

0 голосов
/ 26 ноября 2011

Одна большая проблема с примером кода состоит в том, что синхронизация XMLHttpRequest.send означает, что все выполнение JS должно быть приостановлено в ожидании получения запроса.Нет причин не использовать асинхронный вызов.

Асинхронные вызовы могут улучшить скорость отклика, но они не дают вам координации, что означает, что задача не будет выполняться, пока не будут готовы необходимые данные.Стандартный способ координации асинхронного кода состоит в том, чтобы передать асинхронной функции функцию, которая при выполнении выполняет оставшуюся часть вычислений, основанных на данных.Эта функция имеет техническое название «продолжение», которая представляет собой просто функцию, которая представляет остальную часть вычислений с заданной точки вперед.То есть, поверните:

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

в:

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

Поскольку вы передаете продолжение, это известно как «стиль передачи продолжения».XMLHttpRequest является особым случаем, когда вместо передачи функции асинхронной функции вы устанавливаете ее в качестве прослушивателя для события readystatechange объекта XHR.То есть вы присваиваете продолжение xmlhttp.onreadystatechange.

Есть еще несколько улучшений, которые нужно сделать.Сначала добавьте обнаружение ошибок.Свойство status экземпляра XHR содержит статус HTTP, который вы можете использовать для проверки на наличие ошибок.

Как уже упоминалось рядом других, eval может быть проблематичным, и его следует избегать, когда есть другойвариант.Прежде всего, вы должны убедиться, что строка исходит из надежного источника.Особая проблема с eval заключается в том, что сценарий оценивается в том же контексте, что и вызов eval.Если eval происходит внутри функции, все, что определено сценарием, не видно вне функции.Если вашему сценарию не нужно ничего определять (и вам никогда не нужно будет ничего определять; всегда учитывайте будущее своего кода), вы можете использовать eval.В противном случае динамически создайте элемент script со сценарием в качестве содержимого и добавьте его в документ;Вы можете определить функцию, которая делает это (см. globaleval в приведенном ниже примере).

xmlhttp - это global переменная, что плохо.Вместо этого объявите его как локальную переменную.

Вместо setTimeout, который предназначен для однократных вызовов, используйте setInterval, который периодически вызывает переданную функцию.Обратите внимание, что для выполнения setTimeout и setInterval может потребоваться больше времени, чем заданная задержка, хотя здесь это не должно быть проблемой.

(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();

Если вам не нужно реализовывать все этоСами же, пусть JQuery выполняет тяжелую работу.Хорошо знать, как все делать самостоятельно, но (для производственного кода) использование стандартных библиотек со стандартными интерфейсами ускоряет разработку несколькими способами.

См. Также

0 голосов
/ 25 ноября 2011

Вы пишете:

xmlhttp.responseText.getElementById ( 'part2')

responseText является строкой и не имеет никакого метода getElementById. Вы либо хотите использовать xmlhttp.responseXML.getElementById ("part2"), либо использовать строковые методы для извлечения второй части.

0 голосов
/ 25 ноября 2011

Как и Адам Рэкис, я рекомендую вам использовать $ .ajax действительно просто, попробуйте его ..... но если это не вариант для вас, здесь есть функция, которая используется для выполнения вызовов ajax и работает в IE и Firefox, Chrome я рекомендую вам, если вы не можете использовать Jquery.Проблема в вашей функции не работает в IE, так как у нее нет объекта xmlhttprequest.Надеюсь, это поможет вам.

function newAjaxObject()
{
    var oHttp=false;
    var asParsers=[
         "Msxml2.XMLHTTP.5.0", 
         "Msxml2.XMLHTTP.4.0", 
         "Msxml2.XMLHTTP.3.0", 
         "Msxml2.XMLHTTP", 
         "Microsoft.XMLHTTP"
    ];

    if ( !oHttp && typeof XMLHttpRequest != 'undefined')
    {
        oHttp=new XMLHttpRequest();
    }

 if( !oHttp){
    for (var iCont=0; !oHttp && iCont < asParsers.length; iCont++)
    {
        try
        {
            oHttp=new ActiveXObject(asParsers[iCont]);
        }
        catch(e)
        {
            oHttp=false;
        }
    }
}

   return oHttp;
}
0 голосов
/ 25 ноября 2011

Вы должны реально оценить JS-теги (вручную, либо через eval, либо через вставку DOM).Такая библиотека, как jQuery, сделает это за вас, но если вам нужно использовать собственное решение, вам нужно добавить и это.

...