Комментарии 94
Вообще то это и есть AJAX :) Только реализован на script tag транспорте.
+80
AJAX это асинхронное взаимодействие с сервером средствами Javascript. В приведенном примере и Javascript и взаимодействие в асинхронном режиме есть.
+1
В таком случае завершающий «X» явно лишний :)
+6
Это как раз cross domain scripting, обычные аяксовые запросы и не смогли бы пойти на поддомен гугла.
Себе как раз такой делаю, вот пример
function sendscriptRequest(url, httpParams, callback, callbackArgsArray) {
var currentscript = document.createElement(«script»);
if (httpParams)
httpParams="?rand=" + Math.random() + "&" + httpParams;
else
httpParams="?rand=" + Math.random();
currentscript.ajax_readyState = false;
currentscript.onload = scriptCallback(currentscript, callback, callbackArgsArray);
currentscript.onreadystatechange = scriptCallback(currentscript, callback, callbackArgsArray);
currentscript.src = url + httpParams;
document.getElementsByTagName(«script»)[0].parentNode.appendChild(currentscript);
}
function scriptCallback(currentscript, callback, callbackArgsArray){
return function() {
if (currentscript.ajax_readyState)
return;
if (! currentscript.readyState || currentscript.readyState == «loaded» || currentscript.readyState == «complete») {
currentscript.ajax_readyState = true;
callback.apply(currentscript, callbackArgsArray)
currentscript.parentNode.removeChild(currentscript);
}
}
}
Себе как раз такой делаю, вот пример
function sendscriptRequest(url, httpParams, callback, callbackArgsArray) {
var currentscript = document.createElement(«script»);
if (httpParams)
httpParams="?rand=" + Math.random() + "&" + httpParams;
else
httpParams="?rand=" + Math.random();
currentscript.ajax_readyState = false;
currentscript.onload = scriptCallback(currentscript, callback, callbackArgsArray);
currentscript.onreadystatechange = scriptCallback(currentscript, callback, callbackArgsArray);
currentscript.src = url + httpParams;
document.getElementsByTagName(«script»)[0].parentNode.appendChild(currentscript);
}
function scriptCallback(currentscript, callback, callbackArgsArray){
return function() {
if (currentscript.ajax_readyState)
return;
if (! currentscript.readyState || currentscript.readyState == «loaded» || currentscript.readyState == «complete») {
currentscript.ajax_readyState = true;
callback.apply(currentscript, callbackArgsArray)
currentscript.parentNode.removeChild(currentscript);
}
}
}
-5
Вот здесь хорошая реализация script tag транспорта для GET и winndow name для POST
forum.hivext.ru/index.php?topic=4.0
Работает в FF2+, FF3+, IE6+ IE7+, O9+ Safari3+, Chrome. В IE8 не тестировалось.
forum.hivext.ru/index.php?topic=4.0
Работает в FF2+, FF3+, IE6+ IE7+, O9+ Safari3+, Chrome. В IE8 не тестировалось.
+2
НЛО прилетело и опубликовало эту надпись здесь
Вроде человек, всё верно говорит, чего я заминусовали-то?
XHR же не может выполнять кросс-доменные запросы, вместо этого применяют JSONP (http://www.jstoolbox.com/2009/03/18/chto-takoe-jsonp/)
XHR же не может выполнять кросс-доменные запросы, вместо этого применяют JSONP (http://www.jstoolbox.com/2009/03/18/chto-takoe-jsonp/)
+3
Да есть старенька библиотечка
0
Да есть старенькая библиотечка для JS+PHP
// JSHttpRequest v1.2. © Dmitry Koterov, 2005-01-27.
// forum.dklab.ru/users/DmitryKoterov/
Я как-то совсем про нее забыл, хотя долго ею пользовался. Недавно тоже столкнулся с проблемой обратится AJAX запросом к поддомену. Решение это как раз использовать запросы через подргузку JS массивов
// JSHttpRequest v1.2. © Dmitry Koterov, 2005-01-27.
// forum.dklab.ru/users/DmitryKoterov/
Я как-то совсем про нее забыл, хотя долго ею пользовался. Недавно тоже столкнулся с проблемой обратится AJAX запросом к поддомену. Решение это как раз использовать запросы через подргузку JS массивов
0
Почему старенькая? :-) Есть же свежая версия, она и на moikrug.ru используется (как раз для кросс-доменного AJAX, в частности)…
0
НЛО прилетело и опубликовало эту надпись здесь
«Если пользователь быстро и часто давит на клавиши», не обязательно посылать запрос после каждого нажатия. Ограничение на частоту запросов сделать совсем не сложно.
+8
> Но есть проблема. Если пользователь быстро и часто давит на клавиши, создается некоторое количество параллельных запросов и в результате запрос, отправленный позже может отработать намного раньше более раннего запроса, что повлечет за собой вывод неправильных данных.
а разве указанный подход решает эту проблему? все равно имеется вероятность более раннего окончания загрузки скрипта который запросился позже предыдущего.
а разве указанный подход решает эту проблему? все равно имеется вероятность более раннего окончания загрузки скрипта который запросился позже предыдущего.
+2
Код через <script> выполняется синхронно… тоесть пока не выполниться один ничего другое javascript-овое выполняться не будет. На обычной странице последовательно подключённые скрипты никогда не перемешиваются и выполняются в строгой последовательности… (грузятся может и паралельно, но выполняются точно по порядку)
0
уверены? при асинхронном подключении скриптов это правило неработает. покрайней мере точно не для всех браузеров. ИЕ, Хроме выполняет сразу первый ответивший. ФФ выполняет по порядку добавления. Только что протестировал.
+5
Выложите, если не сложно, сылку на тест… Всё конечно возможно… и если вы правы для меня это будет открытием
>«асинхронное подключения» звучит не правдоподобно для тега
Убеждён, что в следующем коде $ будет доступен сразу после добавления:
var script=document.createElement('script');
script.type='text/javascript';
script.src='jquery.js';
document.body.appendChild(script);
alert($) //ну не будет здесь ошибки ни в одном из браузеров:)
>«асинхронное подключения» звучит не правдоподобно для тега
Убеждён, что в следующем коде $ будет доступен сразу после добавления:
var script=document.createElement('script');
script.type='text/javascript';
script.src='jquery.js';
document.body.appendChild(script);
alert($) //ну не будет здесь ошибки ни в одном из браузеров:)
0
var script=document.createElement('script');
script.type='text/javascript';
script.src='test-slow.js';
document.getElementsByTagName('head')[0].appendChild(script);
var script=document.createElement('script');
script.type='text/javascript';
script.src='test-fast.js';
document.getElementsByTagName('head')[0].appendChild(script);
в test-slow.js и test-fast.js сделайте alert('slow') и alert('slow') соот-но
на ответ test-slow.js поставьте задержку в пару секунд
посмотрите на результ.
точно такие же тесты удалил :). проверил и снес.
script.type='text/javascript';
script.src='test-slow.js';
document.getElementsByTagName('head')[0].appendChild(script);
var script=document.createElement('script');
script.type='text/javascript';
script.src='test-fast.js';
document.getElementsByTagName('head')[0].appendChild(script);
в test-slow.js и test-fast.js сделайте alert('slow') и alert('slow') соот-но
на ответ test-slow.js поставьте задержку в пару секунд
посмотрите на результ.
точно такие же тесты удалил :). проверил и снес.
+3
>на ответ test-slow.js поставьте задержку в пару секунд
А как вы выставляли задержку?
если setTimout-ом то конечно setTimout выполнится после того как загрузится следующий скрипт, а не до.
А как вы выставляли задержку?
если setTimout-ом то конечно setTimout выполнится после того как загрузится следующий скрипт, а не до.
-1
на сервере задержку на ответ. могу вам выложить даже с учетом комментария ниже. если проанализируете, и напишите короткий обзор результатов.
+1
короткий обзор может когда-нибудь… ещё моментов накопится и напишу
0
Ну собственно упомянутые статьи можно найти в ссылках к статье «Загружаем скрипты без блокировки», которая тоже про это.
Эти моменты вроде бы хорошо исследованы.
Эти моменты вроде бы хорошо исследованы.
+1
Так скрипты же не подключаются больше — всего один тег script с изменяемым источником.
0
ну да… если менять src, javascript также остановит выполнение пока не будет сделана загрузка и выполнен скрипт и только потом будет возможно опять изменить src… помоему будет так, но тестов не делал… может sirus выложит тест и развеет все сомнения
-1
так вообще в разных браузерах по разному работает
var script=document.createElement('script');
script.type='text/javascript';
script.src='test2.js';
document.getElementsByTagName('head')[0].appendChild(script);
script.src='test3.js';
FF — сработает только test2.js
ИЕ — сработает только test3.js
var script=document.createElement('script');
script.type='text/javascript';
script.src='test2.js';
document.getElementsByTagName('head')[0].appendChild(script);
script.src='test3.js';
FF — сработает только test2.js
ИЕ — сработает только test3.js
+1
Так, был неправ насчёт одного тега. В коде явно видно создание тегов, глубже пока не смотрел.
А вот поведение дикое какое-то… Сейчас тоже буду тестировать.
А вот поведение дикое какое-то… Сейчас тоже буду тестировать.
0
Гугл делает всё логично — сносит существующий файл (таким образом прерывается загрузка) и создаёт новый.
При изменении src не происходит закачка/парсинг скрипта (FF). Помнится, были обсуждения, как «пнуть» браузер, но совсем ничего не помню… :(
ИЕ же при изменении послушно ползает за каждым файлом. Если в ваш пример добавить задержку при изменении src, то это будет видно. При быстрой же смене загрузка предыдущей версии прерывается.
Т.е. моё предположение могло бы работать в ИЕ =)
При изменении src не происходит закачка/парсинг скрипта (FF). Помнится, были обсуждения, как «пнуть» браузер, но совсем ничего не помню… :(
ИЕ же при изменении послушно ползает за каждым файлом. Если в ваш пример добавить задержку при изменении src, то это будет видно. При быстрой же смене загрузка предыдущей версии прерывается.
Т.е. моё предположение могло бы работать в ИЕ =)
0
> Гугл делает всё логично — сносит существующий файл (таким образом прерывается загрузка) и создаёт новый.
а вы проверяли что загрузка прерывается если снести скрипт который уже в процессе :)?
а вы проверяли что загрузка прерывается если снести скрипт который уже в процессе :)?
0
Бррр… ничего не понимаю… FF не прерывает…
Фик с Гуглом, проблема решается. А почему такое странное поведение?
Для скрипта ставим задержку. В итоге получаем 'a', 'b' и '1' (вывод test1.php). Удаление переменной тоже не помогает. FF цепко держится за подгружаемые файлы…
IE вот обрубает.
Фик с Гуглом, проблема решается. А почему такое странное поведение?
var script1=document.createElement('script');
script1.type='text/javascript';
script1.src='test1.php';
document.getElementsByTagName('head')[0].appendChild(script1);
alert('a');
script1.parentNode.removeChild(script1);
alert('b');
Для скрипта ставим задержку. В итоге получаем 'a', 'b' и '1' (вывод test1.php). Удаление переменной тоже не помогает. FF цепко держится за подгружаемые файлы…
IE вот обрубает.
0
В одно время пользовался библиотекой с похожим принципом- Subsys_JsHttpRequest.
В ней реализована передача php переменных в js посредством script tag.
Кроссбраузернасть отличная.
В ней реализована передача php переменных в js посредством script tag.
Кроссбраузернасть отличная.
0
НЛО прилетело и опубликовало эту надпись здесь
0
Упс. Ну, вообще говоря, в JsHttpRequest поддерживаются 3 транспорта: script, XMLHttpRequest, а также IFRAME — для закачки файлов аяксом на сервер. Плюс автоматом выбирается оптимальный (из тех, что поддерживает текущий браузер, в зависимости от кроссдоменности и т.д.). Но, конечно, есть и отдельный версии библиотеки, по одной на каждый вид транспорта (например, можно взять только JsHttpRequest-script.js, в которой ничего, кроме script-транспорта, нет).
+3
У Гугла-то все круто :)
А вот по поводу этого:
> «Но есть проблема. Если пользователь быстро и часто давит на клавиши, создается некоторое количество параллельных запросов и в результате запрос, отправленный позже может отработать намного раньше более раннего запроса, что повлечет за собой вывод неправильных данных.»
Это как так??
1. Пользователь наживает «а»
2. Отправляется запрос "...&query=а"
3. Пользователь наживает «б»
4.1. Если запрос на «а» еще не отработал — отменяется запрос на «а».
4.2. Если запрос на «а» уже отработал — просто уже отображаются результаты поиска на «а».
5. Отправляем запрос "...&query=аб"
и так далее.
В чем проблема-то? Каждый запрос отменяет предыдущий, если тот еще не отработал и одновременно содержит его в себе (как «аб» содержит «а»), да и все.
А вот по поводу этого:
> «Но есть проблема. Если пользователь быстро и часто давит на клавиши, создается некоторое количество параллельных запросов и в результате запрос, отправленный позже может отработать намного раньше более раннего запроса, что повлечет за собой вывод неправильных данных.»
Это как так??
1. Пользователь наживает «а»
2. Отправляется запрос "...&query=а"
3. Пользователь наживает «б»
4.1. Если запрос на «а» еще не отработал — отменяется запрос на «а».
4.2. Если запрос на «а» уже отработал — просто уже отображаются результаты поиска на «а».
5. Отправляем запрос "...&query=аб"
и так далее.
В чем проблема-то? Каждый запрос отменяет предыдущий, если тот еще не отработал и одновременно содержит его в себе (как «аб» содержит «а»), да и все.
0
Отправляем запрос «а».
Отправляем запрос «б».
Отправляем запрос «в».
Запрос «б» завершился.
Запрос «в» завершился.
Запрос «а» завершился.
В итоге имеем результат не по «абв», а по «а».
Запросы ведь друг друга не убивают. Они параллельно висят.
Отправляем запрос «б».
Отправляем запрос «в».
Запрос «б» завершился.
Запрос «в» завершился.
Запрос «а» завершился.
В итоге имеем результат не по «абв», а по «а».
Запросы ведь друг друга не убивают. Они параллельно висят.
-3
>Запросы ведь друг друга не убивают. Они параллельно висят.
Откуда такая уверенность?))
Откуда такая уверенность?))
0
Час назад проверяли.
+2
Запросы отменяете, если они еще не обработаны.
Вообще объект suggest-а должен содержать некий пул и «знать», какой запрос отправлен последним.
Вообще объект suggest-а должен содержать некий пул и «знать», какой запрос отправлен последним.
0
Ну это уже косяк разработчиков. То что это реализуемо, потому что сие очень даже реализуемо.
+1
Я бы поотрывал яйца Client-side разработчикам, которые для Suggest-поиска могут сделать параллельные запросы по каждой букве :)
+2
Я бы тоже. Но у меня их мало осталось (разработчиков), экономлю.
0
Гугловский suggest срабатывает и по каждой букве тоже, если печатать не слишком быстро. Дело скорее в количестве запросов в единицу времени, а не в степени изменения текста запроса.
0
Ну я же здесь вот уже написал, как оно должно срабатывать. Ничего страшного, если печатается буква и она уже успела обработаться — последующий запрос ее также содержит и выдаст более новые результаты.
И по поводу Гугла — я не смотрел в деталях, но предполагаю, что у них запросы (если печатать мееееедлеееенно):
d
de
dev
deve
devel
develo
develop
а не:
d
e
v
e
l
o
p
Или нет?
И по поводу Гугла — я не смотрел в деталях, но предполагаю, что у них запросы (если печатать мееееедлеееенно):
d
de
dev
deve
devel
develo
develop
а не:
d
e
v
e
l
o
p
Или нет?
0
d
de
dev
devi < — опечатка
dev
deve
de
dev
devi < — опечатка
dev
deve
0
Ну и не страшно — если медленно печатаем — успевают, естественно, открыться результаты для «devi» — ведь откуда компьютеру знать, что есть опечатка, а что нет.
Если быстро и сразу исправили — нужно сделать, чтобы следующий запрос на «dev» или «deve» отменил запрос на devi. А еще можно включить функциональность таймера и запускать запрос с маленькой, но задержкой (мы, к слову, так и делали при необходимости) — пользователь обычно успевал написать все слово поиска, не отправив ни одного запроса «посреди» слова.
Если быстро и сразу исправили — нужно сделать, чтобы следующий запрос на «dev» или «deve» отменил запрос на devi. А еще можно включить функциональность таймера и запускать запрос с маленькой, но задержкой (мы, к слову, так и делали при необходимости) — пользователь обычно успевал написать все слово поиска, не отправив ни одного запроса «посреди» слова.
0
Я об этом и говорю — можно добавить таймеры, проверялки, отменялки. А можно и проще, хоть и не элегантно. Кому как нравится и у кого сколько времени на ту или иную задачу.
0
Возможно, но отправка каждой буквы по отдельности — сама по себе концептуальная ошибка. То есть, таким образом, вы сами создаете себе дополнительную проблему, которую в итоге приходится решать разными костылями.
P.S. А Suggest-поиск — сама по себе отнюдь не сложная вещь, к тому же есть готовые решения.
P.S. А Suggest-поиск — сама по себе отнюдь не сложная вещь, к тому же есть готовые решения.
0
А отправлять по одной букве — это не моя идея. Я говорил про отправку введенных слов.
0
А по-моему, не совсем
Ну как бы там ни было, тогда самая обычная отправка запросов друг за другом вполне может подойти для вашей «быстрой» задачи.
P.S. Таймер добавить — пара минут.
Ну как бы там ни было, тогда самая обычная отправка запросов друг за другом вполне может подойти для вашей «быстрой» задачи.
P.S. Таймер добавить — пара минут.
0
Аааа, я думал, что «по каждой букве» значит «после каждого изменения текста», прошу прощения :)
0
Я смотрел как работет suggest box в GWT- он заранее содержит в себе
массив из слов для показа подсказки к любой букве, т.е. какую бы букву не нажал пользователь, у suggest box будут варианты подсказок и прользователю не нужно ждать
результата запроса.
Правда в дальнейшем для добавления в массив новых значений
всё-равно придётся ждать завершения запроса. Но, так как запрос работает на опережение, указанная проблема (ошибочный результат подсказки) не возникает.
массив из слов для показа подсказки к любой букве, т.е. какую бы букву не нажал пользователь, у suggest box будут варианты подсказок и прользователю не нужно ждать
результата запроса.
Правда в дальнейшем для добавления в массив новых значений
всё-равно придётся ждать завершения запроса. Но, так как запрос работает на опережение, указанная проблема (ошибочный результат подсказки) не возникает.
0
имхо, можно было бы сделать так, чтобы не делать запрос на каждую введенную букву, ведь запрос например массива начинающегося на «абв» содержит внутри себя массив начинающийся с «абвг». Можно было бы сделать это отсеивание на стороне клиента (когда пользователь ввел допустим больше 5 букв и масси уже не очень большой).
Хотя надо наверно потестить — как быстрее и оптимальнее.
Хотя надо наверно потестить — как быстрее и оптимальнее.
0
AJAX — это общая концепция.
XMLHttpRequest — это конкретная технология, причём никто не говорил, что единственная.
Когда XMLHttpRequest ещё не «раскручен» был и не всеми браузерами поддерживался, повсеместно использовались скрытые iframes — тоже ведь аяксом являлось.
XMLHttpRequest — это конкретная технология, причём никто не говорил, что единственная.
Когда XMLHttpRequest ещё не «раскручен» был и не всеми браузерами поддерживался, повсеместно использовались скрытые iframes — тоже ведь аяксом являлось.
+3
Посмотрел в википедии. Там как раз эти 3 способа и описаны («гугловский», «ифреймовский» и «иксэмэльреквестный»)
ru.wikipedia.org/wiki/AJAX
ru.wikipedia.org/wiki/AJAX
+5
На мой взгляд, после этого коммента обсуждать в посте уже нечего. :)
+6
на самом деле советую почитать английскую страничку википедии en.wikipedia.org/wiki/Ajax_(programming)
там этот термин более широко трактуется, однажды чуть не сел в лужу с этим в очередной дискуссии
там этот термин более широко трактуется, однажды чуть не сел в лужу с этим в очередной дискуссии
0
единственное, что меня лично смущает, так это кеширование… (чтобы после запроса abcd запрос abc не загружался с сервера, а подгружался из локального)
либо в этом случае браузер сам выполняет функцию кеша?..
либо в этом случае браузер сам выполняет функцию кеша?..
0
сам в данный момент столкнулся с этой проблемой. К сожалению, гугление ничего не дает.
Нужно подобие Suggest'а у гугла, но в итоге нужно получить таблицу с записями. Если вводить слово быстро, то в таблице появляются дублированные записи. После «передышки» и ввода следующей буквы, все встает на свои места.
setTimeout не помогает (
Нужно подобие Suggest'а у гугла, но в итоге нужно получить таблицу с записями. Если вводить слово быстро, то в таблице появляются дублированные записи. После «передышки» и ввода следующей буквы, все встает на свои места.
setTimeout не помогает (
0
ну вот. Стоило написать, как проблема вроде как решилась. Обнуление контента таблицы вызывалось в той же функции, которая вызывает «дочернюю» через setTimeout().
А надо было делать в той, которая вызывается непосредственно в setTimeout() =)
А надо было делать в той, которая вызывается непосредственно в setTimeout() =)
0
А я всегда считал, что метод XMLHttpRequest.abort() отменяет текущий запрос. Помоему, все браузеры такого же мнения.
+1
>>Но есть проблема. Если пользователь быстро и часто давит на клавиши, создается некоторое количество параллельных запросов и в результате запрос, отправленный позже может отработать намного раньше более раннего запроса, что повлечет за собой вывод неправильных данных.
Заблокируйте кнопку при первом нажатии, и пока не придет ответ такой оставляем. И это не Аякс, а упреждающая выборка из кеша браузера. Вот пример под ROR — leopard.in.ua/2009/03/30/molnienosnoe-javascript-avtozapolnenie/
Заблокируйте кнопку при первом нажатии, и пока не придет ответ такой оставляем. И это не Аякс, а упреждающая выборка из кеша браузера. Вот пример под ROR — leopard.in.ua/2009/03/30/molnienosnoe-javascript-avtozapolnenie/
-5
Вы грустные вещи пишите
-3
Есть еще вариант отправлять клиенту выборку, допустим, по первым трем буквам, а уже на клиенте отсекать по остальным введенным буквам.
плюсы:
1. всего один запрос на сервер
2. фильтрация по буквам дальше третьей на клиенте происходит почти мгновенно (хорошо для опечаток)
минусы:
1. не подходит для больших выборок
плюсы:
1. всего один запрос на сервер
2. фильтрация по буквам дальше третьей на клиенте происходит почти мгновенно (хорошо для опечаток)
минусы:
1. не подходит для больших выборок
0
Этот протокол называется JSONP.
+4
была на хабре статья, где google suggest подробно разбирали по косточкам.
0
хм… у них уже так довольно давно. Все берется динамическим созданием script.
притом при частом нажатии клавиш параллельные запросы ajax можно легко поблочить или их отслеживать, просто выставлять флаг отправки запроса и получения ответа =/
притом при частом нажатии клавиш параллельные запросы ajax можно легко поблочить или их отслеживать, просто выставлять флаг отправки запроса и получения ответа =/
0
НЛО прилетело и опубликовало эту надпись здесь
А я таким образом эту проблему решаю: habrahabr.ru/blogs/webdev/17884/
0
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Suggest в Google — никакого аякса