Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ajax, проблема с "hello, World!"
Форум программистов > Интернет и сети > Web 2.0, AJAX, Ruby, RSS технологии
Flying
Собственно, начал часов 10 назад изучение ajax, написал свое первое аякс-приложени: смена числа на другое случайное число при нажатии на кнопку. Функцию, которая отправляет запрос ксерверному скрипту, содрал из книги "Изучаем Ajax" (Бретт Маклафлин), в этой части всё правильно, своего кода там килобайт-другой... Скрипт этот работает в эксплоере, а вот в опере и мозилле - нет sad.gif, над этими строчками изрядно посидел, но никак не пойму в чем дело. Почему оно не работает в моих любимых браузерах? Помогите, кому не лень!

Вот привожу код:

1) клиентская часть:
<html>
<head>
<title>Test</title>
<script language="Javascript">
function createRequest() {
    request = null
    try {
        request = new XMLHttpRequest();
    } catch (trymicrosoft) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }
    
    if (request == null)
        alert(" :-( ___ Error creating request object! ");

return request;

}

function refreshRandNumber() {
    request = createRequest();
    var url = "ajax/randNumber.php";
    request.open("GET", url, true);
    request.onReadyStateChange = updateRandNumber;
    request.send(null);
}

function updateRandNumber() {
    if (request.ReadyState == 4) {
        document.getElementById("randNum").innerHTML = request.responseText;
    }
}
</script>
</head>    
<body>

<br><br><br>
<h1>Random number: <span id="randNum" style="color:red;">still empty!</span></h1>
<input type="button" value="REFRESH!" onclick="refreshRandNumber();">
<br><br><br>
    
</body>
</html>


2) серверная smile.gif
<?= rand(0,100); ?>


Создает запрос кроссбраузерная функция, запрос не null, но дальше не работает...


ЗЫ: в подключение фреймворков прошу носом меня не тыкать, т.к. с азами не разобрался
etc
Что такое "не работает"?
Flying
"не работает" - это значит, что при нажатии кнопки "REFRESH!" надпись "still empty!" не меняется на случайное число... в Internet Explorer работает ("работает" - значит при нажатии кнопки "REFRESH!" надпись "still empty!" меняется на какое-то число, а при последующих нажатиях в 99% случаев это число меняется на новое число из диапазона от 0 до 100).

Вот в Internet Explorer работает, а в других - нет, почему smile.gif ? Вроде бы объект request создается во всех браузерах (функция createRequest() возвращает не null), хотя нужного результата нет
etc
Цитата(Flying @ 6:06:2008 - 09:08) *
функция createRequest() возвращает не null
Как узнали?
Flying
Цитата(etc @ 6:06:2008 - 07:16) *
Как узнали?


после строчки
    request = createRequest();

добавил
    alert(request);

мозилла показывает алерт с надписью "[Object XMLHttpRequest]"
etc
Теперь добавте ее-же перед
if (request.ReadyState == 4) {
в callback'е что произойдет?
Flying
Цитата(etc @ 6:06:2008 - 08:05) *
в callback'е что произойдет?


добавлял, везде добавлял... в браузерах, где не работает, до callback-функции вообще не доходит т.к. алерты в ней не срабатывают. Но вот почему в этом скрипте функция updateRandNumber вообще не вызывается, я не пойму...
etc
ну вот, пойдем дальше ... раз пока не понимаете, то сразу после
<script language="Javascript">

вставте вот такое -
var request = null;
, как изменилось поведение?
Flying
да вроде никак не изменилось,

    alert(request);
    request = createRequest();
    alert(request);

сначала request нулл, потом объект... алерты в callback по-прежнему не работают
etc
Показывайте весь код.
Flying
<html>
<head>
<title>Test</title>
<script language="Javascript">

var request = null;

function createRequest() {
    request = null
    try {
        request = new XMLHttpRequest();
    } catch (trymicrosoft) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }
    
    if (request == null)
        alert(" :-( ___ Error creating request object! ");

return request;

}

function refreshRandNumber() {
    request = createRequest();
    var url = "ajax/randNumber.php";
    request.open("GET", url, true);
    request.onReadyStateChange = updateRandNumber;
    request.send(null);
}

function updateRandNumber() {
    alert("Yeah!");
    if (request.ReadyState == 4) {
        document.getElementById("randNum").innerHTML = request.responseText;
    }
}
</script>
</head>    
<body>

<br><br><br>
<h1>Random number: <span id="randNum" style="color:red;">still empty!</span></h1>
<input type="button" value="REFRESH!" onclick="refreshRandNumber();">
<br><br><br>
    
</body>
</html>


вот и весь незамысловатый код

Усли переменной var url = "ajax/randNumber.php" назначать абсолютный путь, то это ничего не меняет...
etc
function createRequest() {
    if (request != null)
        return;

    try {
        request = new XMLHttpRequest();
    } catch (trymicrosoft) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }

    if (request == null)
        alert(" :-( ___ Error creating request object! ");

    request.onReadyStateChange = updateRandNumber;
}

function refreshRandNumber() {
    createRequest();
    var url = "ajax/randNumber.php";
    request.open("GET", url, true);
    request.send(null);
}
так поменяйте эти методы.

ой а зачем request.send(null);? просто request.send();

и
request.open("GET", url, true);
на
request.open("GET", url, false);
Flying
вот такое по-прежнему в ИЕ работает, в опере - нет. Может карма не в порядке...

<html>
<head>
<title>Test</title>
<script language="Javascript">

request = null;

function createRequest() {
    if (request != null)
        return;

    try {
        request = new XMLHttpRequest();
    } catch (trymicrosoft) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }

    if (request == null)
        alert(" :-( ___ Error creating request object! ");

    request.onReadyStateChange = updateRandNumber;
}

function refreshRandNumber() {
    createRequest();
    var url = "ajax/randNumber.php";
    request.open("GET", url, false);
    request.send();
}

function updateRandNumber() {
    alert("Yeah!");
    if (request.ReadyState == 4) {
        document.getElementById("randNum").innerHTML = request.responseText;
        request = null;
    }
}
</script>
</head>    
<body>

<br><br><br>
<h1>Random number: <span id="randNum" style="color:red;">still empty!</span></h1>
<input type="button" value="REFRESH!" onclick="refreshRandNumber();">
<br><br><br>
    
</body>
</html>


в ИЕ и число меняется, и алерт выдается, в опере - ничего не происходит

ЗЫ: прочитал добавление, сейчас попробую... менять true на false пробовал уже, кстати, сейчас нулл убрать попробую

ЗЗЫ: и опять не работает
etc
Цитата(Flying @ 6:06:2008 - 11:54) *
request = null;
где var?
Цитата(Flying @ 6:06:2008 - 11:54) *
опять не работает

быть того не может, ошибку пишет или нет?
Flying
Цитата(etc @ 6:06:2008 - 10:11) *
быть того не может, ошибку пишет или нет?

var добавил, все равно не работает | не работает без ошибок, просто при нажатии на кнопку "РЕФРЕШь!" ничего не происходит

сейчас какой-нить браузер другой поставлю... ХЗ что это...

В еще одной мозилле не работает *wall*
не судьба, звезды не так лягли, луна не в той фазе или тупо руки кривые...

----
надо заново с ajax начать, по-другому как-нить
etc
request.onReadyStateChange = updateRandNumber;
на
request.onreadystatechange = updateRandNumber;

Цитата(Flying @ 6:06:2008 - 12:59) *
надо заново с ajax начать, по-другому как-нить
тут не в этом дело, просто во первых это скрипт, во вторых разница в реализаций, ну а в третьих smile.gif как правило все пользуют какиенить библиотеки готовые, и поэтому на такие вещи внимание особо не обращаешь.


Но писать надо сразу правильно, поэтому то, надо и var писать и все вот такие мелочи.
Flying
Цитата(etc @ 6:06:2008 - 12:08) *
request.onReadyStateChange = updateRandNumber;
на
request.onreadystatechange = updateRandNumber;


омг, помогло в какой-то степени smile.gif, теперь в опере вызывается функция updateRandNumber (алерты, расположенные в ней, работают), в моззиле все также, как и было... зато значение request.responseText в опере всегда равно 28 smile.gif. Ну и ужас, onreadystatechange должно быть в нижнем регистре, а responseText по-верблюжьи, имхо это нелогично

в общем это ужас: в одном браузере так, в другом этак, в третьем вообще свои дебильные "особенности"... уж лучше сразу какой-нить фреймворк осваивать, который работает на 100%, prototype почему-то мне кажется подходящим, по отзывам распространен и доки на русском есть
etc
Цитата(Flying @ 6:06:2008 - 21:09) *
имхо это нелогично
В программировании вообще, а в "скриптовом" особенно, логику искать весьма проблематично. smile.gif
Цитата(Flying @ 6:06:2008 - 21:09) *
уж лучше сразу какой-нить фреймворк осваивать, который работает на 100%
Ага, советую ajax.asp.net wink.gif, только вот 100% никто не гарантирует.
Flying
etc, спасибо за помощь

Все-таки сделал я, чтоб оно работало в трех браузерах:

<html>
<head>
<title>Test</title>
<script language="Javascript">

var request = null;

function createRequest() {
    if (request != null)
        return;

    try {
        request = new XMLHttpRequest();
    } catch (trymicrosoft) {
        try {
            request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (othermicrosoft) {
            try {
                request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (failed) {
                request = null;
            }
        }
    }

    if (request == null)
        alert(" :-( ___ Error creating request object! ");

}

function refreshRandNumber() {
    createRequest();
    var url = "ajax/randNumber.php?q=1";
    request.onreadystatechange = updateRandNumber;
    request.open("GET", url, true);
    request.send(null);
}

function updateRandNumber() {
    if (request.readyState == 4) {
        document.getElementById("randNum").innerHTML = request.responseText;
        request = null;
    }
}
</script>
</head>    
<body>

<br><br><br>
<h1>Random number: <span id="randNum" style="color:red;">still empty!</span></h1>
<input type="button" value="REFRESH!" onclick="refreshRandNumber();">
<br><br><br>
    
</body>
</html>


Цитата(etc @ 7:06:2008 - 09:15) *
В программировании вообще, а в "скриптовом" особенно, логику искать весьма проблематично.

эт точно:

1. Если request.send(), то не работает в мозилле, с request.send(null) работает
2. Если url = "ajax/randNumber.php?q=1" изменить на url = "ajax/randNumber.php", то опера будет кэшировать этот запрос, вообще для 100% пробивания кэша над делать с Date().egtTime()...
3. onreadystatechange должно быть в нижнем ркгистре, иначе в опере и мозилле не работает
4. request.open("GET", url, true), false - не работает в мозилле, хотя хз почему так
etc
Цитата(Flying @ 8:06:2008 - 19:53) *
1. Если request.send(), то не работает в мозилле, с request.send(null) работает
у меня работает request.send() везде.
Цитата(Flying @ 8:06:2008 - 19:53) *
то опера будет кэшировать этот запрос
Все нормальные браузеры будут кэшировать. И вообще кэширование для этого и создано, а вот программист должен смотреть если его функционал должен в любом случае посылать апрос, то надо делать соотв действия. Правда у нас часто делают это когда надо и когда нет.
Цитата(etc @ 6:06:2008 - 14:08) *
request.open("GET", url, true), false - не работает в мозилле, хотя хз почему так
Хм... лень искать, но вроде это именно в мозилле баг, она не умеет работать в асинхронном режиме, за что и отвечает 3 параметер.
По крайней мере опять же у меня работает только с false.

Упс ... я имею ввиду под мазилой - FireFox (у меня сейчас 2.0.0.14), а вы?
Flying
моя мозилла - firefox 2.0.0.11 и она, о чудо rolleyes.gif , работает только в асинхронном режиме

жесткая вещь - ajax, если применять буду, то проверять на работоспособность при загрузке страницы было бы логично (?): например обращаться к тестовому скрипту на сервере, и если от него приходит верный ответ - формировать страницу с ajax, если неверный или вообще никакой - без ajax... перед этим проверять включен ли JS... или что-то типа того, т.к. добиться 100% поддержки скрипта всеми браузерами как-то нереально, а терять посетителей на сайте из-за неработоспособности нехорошо
etc
Цитата(Flying @ 9:06:2008 - 12:02) *
моя мозилла - firefox 2.0.0.11 и она, о чудо , работает только в асинхронном режиме
а попробуйте отправить сразу несколько запросов (не дожидаясь ответа), а на сервере для убедительности в коде поставте задержку секунды на две, инетерсно, что будет?
Цитата(Flying @ 9:06:2008 - 12:02) *
жесткая вещь - ajax
ну так а что вы хотите, стандартов то нет, как в прочем на dhtml в целом, вот все и куралесят как хотят, а договориться не могут/хотят, отсюда и имеем.
Цитата(Flying @ 9:06:2008 - 12:02) *
проверять на работоспособность
так то оно так, но тут тоже смотря что делаете, и как вам (заказчику) надо. все от условий, вот мы пишем сейчас, так ни каких проверок (грубо говоря), не хотят юзать javascript - в сад, без разговоров. wink.gif И еси смотреть куда все идет, так и смысла практически нет. Сайтов (это все, и особенно корпаративные приложения! а не поделок) которые работают без dhtml уже (почти) нет. Ajax - silverlight -... уже завоевали(или скоро) популярность.
С другой стороны Ajax - это уменьшения трафика в целом, и кто думает что это наоборот, мягко говоря еще не понимают.
Flying
Цитата(etc @ 9:06:2008 - 12:18) *
а попробуйте отправить сразу несколько запросов (не дожидаясь ответа), а на сервере для убедительности в коде поставте задержку секунды на две, инетерсно, что будет?

получился неописуемый ужас smile.gif, и в мозилле, и в опере... при 2-3 одновременных запросах кое как работает все, если много раз нажать, то в мозилле вместо числа получается ничего, а в опере вместо одного числа много чисел, хотя логично было бы полю randNum содержать результат последнего запроса... лучше кнопку делать disabled на время запроса

Цитата(etc @ 9:06:2008 - 12:18) *
Сайтов (это все, и особенно корпаративные приложения! а не поделок) которые работают без dhtml уже (почти) нет

это да, в общем ajax, js, css прокачивать надо
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2008 IPS, Inc.