AJAX — как сделать запрос к PHP-коду без перезагрузки страницы
Эта тема имеет больше общего с JavaScript, но ввиду того, как часто у новичков возникают вопросы вроде «Как выполнить функцию PHP из JavaScript-кода?» или «Как отправить форму без перезагрузки?», она напросилась в этом разделе сама самой.
Итак, AJAX — это Asynchronous Javascript And XML — асинхронный JavaScript и XML, если по-русски. Разберём каждое слово:
1) Асинхронный — это и есть то самое, чего все так хотят — выполнение действий без перезагрузки страницы. Пока JavaScript отправил запрос на сервер, пользователь продолжает выполнять действия на странице, т.к. никаких переходов при отправке запроса не происходит.
2) JavaScript — язык программирования, который используют инструменты для отправки AJAX-запросов. Т.к. статья для новичков, то подразумевается, что вы используете либо только чистый JavaScript, либо в совокупности с jQuery. Если вы не используете jQuery, то для создания такого запроса требуется создание объекта XMLHttpRequest. В jQuery всё немного проще и лаконичнее — вы пользуетесь методами $.post и $.get для отправки соответствующих запросов. Когда нужно использовать post, а когда get — чуть позже.
3) XML — в контексте этой статьи это не так важно, считайте это отсылкой к тому самому объекту XMLHttpRequest, ведь сначала появился именно этот способ.
Таким образом, AJAX — это способ отправки запросов (и данных) на сервер без перезагрузки страницы и, как следует, прерывания действий пользователя.
Обычно, любой запрос сопровождается некоторыми параметрами. В GET-запросах такие параметры передаются в URL, например: http://site.com/index.php?param1=value1¶m2=value2 . Это накладывает два ограничения:
1) Объём отправляемых данных существенно ограничен — объём классического GET-запроса находится в диапазоне от 2 до 8 килобайт по умолчанию.
2) Данные открыты — не желательно передавать чувствительные данные, например — пароли. Из-за этого, POST-запросы встречаются намного чаще.
У POST-запроса, в отличие от GET, есть тело, которое помещается после заголовка (а GET-запрос имеет только его). Данные тела явно не передаются (относительно — трафик можно прослушать, но это уже вопрос применения шифрования и защищенного канала). Объём информации, который можно передать в теле, опять же, зависит от настроек сервера. По умолчанию, этот объём порядка 20 мегабайт. И, разумеется, можно передавать GET-параметры через URL. В общем случае, POST-запросы являются более гибкими.
Теперь рассмотрим отправку этих двух видов запросов с помощью обозначенных выше методов — с помощью объекта XMLHttpRequest и методов jQuery — $.post и $.get.
В качестве примера используем следующий «скрипт»:
$name = $_GET['name']; echo "Hello, $name!";
var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { alert(this.responseText); } else { alert('Произошла ошибка!'); } }; xmlhttp.open("GET", "hello.php?name=Webkill", true); xmlhttp.send(null);
В строке один происходит создание объекта. Во второй мы присваиваем этому объекту свойство onreadystatechange — функцию, которая будет выполнена, когда
будет получен ответ на запрос. Такая функция называется callback (колбэк). В ней мы обрабатываем два случая — когда запрос прошел нормально, и когда произошла ошибка.
В 10-той строке мы вызываем метод, в который передаём три параметра:
1) «GET» — тип запроса
2) «hello.php?name=Webkill» — URL запроса: файл hello.php и один параметр name.
3) true — асинхронность. Если false — то браузер будет ожидать ответа (синхронность).
На 11-ой строке происходит отправка запроса, при этом мы указываем один параметр — null (позже, через этот параметр будут передаваться данные тела POST-запроса).
$.get("hello.php", {name: "Webkill"}, function(data) { alert(data); } );
Собственно, отправка GET-запроса в jQuery заключается в вызове метода $.get с тремя параметрами:
1) «hello.php» — часть URL без GET-параметров
2) — параметры запроса в виде ассоциативного массива (JSON)
3) Функция-обработчик, которая вызывается в случае «успеха»
Допустим, нужно сделать аутентификацию без перезагрузки страницы. GET-запрос не подходит, т.к. передаётся пароль.
$login = 'Webkill'; $pass = 'qwerty123'; if($_POST['login'] == $login && $_POST['password'] == $pass) { echo 'Добро пожаловать!'; } else { echo 'В доступе отказано.'; }
var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { alert(this.responseText); } else { alert('Произошла ошибка!'); } }; xmlhttp.open("POST", "login.php", true); xmlhttp.send({login: inputLogin, pass: inputPassword});
Легко заметить, что в целом код не изменился. Поменялся только первый параметр функции open — тип запроса, и теперь мы передаём данные в метод send в формате JSON.
$.post('login.php', {login: inputLogin, pass: inputPassword}, function(data) { alert(data); } );
Снова, изменений немного: только название метода говорит о том, что в этот раз мы шлём POST-запрос. В случае GET-запроса параметры, которые мы передаём в JSON, закодируются в URL, а в случае POST — попадут в тело запроса. Если вы хотите использовать GET-параметры в POST-запросе, то необходимо их писать в URL вручную.
Естественно, круг задач, для которых используется AJAX намного шире — загрузка файлов, игры и т.д. Целью этой статьи является ознакомление с этим комплексом технологий. Стоит отметить, что в случае jQuery можно обрабатывать намного больше вариантов ответа сервера с помощью функций done, fail и always. Также, функции-обработчики кроме собственно ответа принимают и другие параметры.
xmlhttp.open() target the same page
I need some help getting the included ajax script’s xmlhttp.open() to target a php code within the same page —something like $_SERVER[PHP_SELF] here is the script:
var url = window.location.pathName + '?q=' + strss; alert(url);//to inspect the url string. xmlhttp.open("GET", url, true);
Mbar, That’s different question. The code is doing exactly what is was written to do, namely to insert the ajax responseText into DOM element «livesearch3». If you want something different to be inserted, then you have to adapt the server-side script to return something different. Alternatively, call …
Mossa, I can’t see anything that should make you abandon your method. It’s just a question of getting the detail right. As far as I can tell, the client id remains in the ‘clientID’ field and is therfore available to be sent as a parameter in as …
Great angle! I’m attempting the strategy now!
Does it make a difference if in the getClient.php, I added
echo "formObj.returnedClientId.value = '".toSafeString($inf["clientID"])."';\n"; echo "formObj.returnedClientId.value = '';\n";
echo "formObj.returnedClientId.value = " . $_GET['getClientId']; echo "formObj.returnedClientId.value = ''";
All 17 Replies
xmlhttp.open("GET", window.location.pathName+strss, true);
Thank you air show for the post. how do I get the variable inside the php script since the $q variable is not in the syntax. I know normally I would get it like this:
var url = window.location.pathName + '?q=' + strss; alert(url);//to inspect the url string. xmlhttp.open("GET", url, true);
Thanks Airshow. There is definitely progress with the last solution. However, when the alert appears —displaying the correct path and the correct $q variable, after click the ok button, a duplicate of the same page loads at the bottom. I have echo’ed the $q inside the php code, it only appears in the duplicate page. Nothing happens when I comment out the alert(url); Any thoughts!
Mbar, That’s different question. The code is doing exactly what is was written to do, namely to insert the ajax responseText into DOM element «livesearch3». If you want something different to be inserted, then you have to adapt the server-side script to return something different. Alternatively, call a different script (ie. a different php file) which is designed to return the content you desire. Typically, in applications that employ ajax, you initially serve one page to provide all the peripheral HTML content (doctype, metas, styles, javascript, masthead, primary navigation, controls, page footer . ) and skeleton elements (eg divs and spans) to accommodate ajax responses. Then, on various user interactions, you call one or more scripts (typically NOT the original page) to provide additional/alternative page content (eg search results). If your php file is set up to deliver the whole page every time (from !doctype through to