AJAX (асинхронний JavaScript та XML) — це засіб завантаження даних із сервера без перезавантаження сторінки. Він використовує функціональність вбудованого в браузер XMLHttpRequest (XHR), щоб зробити запит на сервер, а потім обробити отримані від сервера дані.
jQuery пропонує метод $.ajax і кілька зручних методів, щоб спростити роботу з XHR у всіх браузерах.
$.ajax
Ми можемо використовувати метод $.ajax() Декількома шляхами: можемо передати об'єкт конфігурації як єдиний аргумент або можемо передати адресу та необов'язковий об'єкт конфігурації. Давайте подивимося в першому наближенні:
<code data-language="javascript">//Створюємо функцію «обробника», яка викликається, коли... //...запит AJAX успішний var updatePage=function( resp) { $( '#target').html( resp.people[0].name); }; //...запит AJAX провалився var printError=function( req, status, err) { console.log( 'щось пішло не так', status, err); }; //Створюємо об'єкт для опису запиту AJAX var ajaxOptions={ url: '/data/people.json', dataType: 'json', success: updatePage, error: printError }; //Ініціалізуємо запит! $.ajax(ajaxOptions);
Звичайно, ви можете бути менш багатослівними, просто передаючи літеральний об'єкт у метод $.ajax() і застосовуючи анонімні функції для success і error. Така версія простіше для написання і її, ймовірно, простіше підтримувати: $.ajax({ url: '/data/people.json', dataType: 'json ', success: function( resp) { $( '#target').html( resp.people[0].name);}, error: function( req, status, err) { console.log( 'щось пішло не так', status, err); } });
Як згадувалося раніше, ви можете викликати метод $.ajax() , передаючи йому адресу та необов'язковий об'єкт конфігурації. Це може бути корисно, якщо ви хочете використовувати конфігурацію за промовчанням для $.ajax() або якщо ви бажаєте використовувати ту ж конфігурацію для декількох адрес.
<code data-language="javascript">$.ajax( '/data/people.json', { type: 'GET', dataType: 'json', success: function( resp) { console.log( resp.people) ; }, error: function( req, status, err) { console.log( 'щось пішло не так', status, err); } });
У цій версії обов'язкова тільки адреса, але об'єкт конфігурації дозволяє нам сказати jQuery, які дані ми хочемо передати, який використовувати метод HTTP (GET, POST та ін.), які дані ми очікуємо отримати, як реагувати коли запит успішний чи ні і багато іншого.
>Дивіться документацію за $.ajax() для отримання повного списку параметрів конфігурації.
А — це асинхронний
Запити AJAX виконуються асинхронно — це означає, що метод $.ajax повертає значення до завершення запиту і, отже, до виконання функції success. Це означає, що оператор return цієї функції виконається до завершення запиту. Це означає, що функція getSomeData з прикладу нижче поверне data до її визначення, внаслідок чого код видасть помилку.
Увага! Неправильний код
<code data-language="javascript">var getSomeData=function() { var data; $.ajax({ url: '/data/people.json', dataType: 'json', success: function(resp) { data=resp.people; } }); return data; } $( '#target').html( getSomeData().people[0].name);
Х — це JSON
Термін AJAX був придуманий у 2005 році для опису методу вилучення даних із сервера без необхідності оновлення сторінки . Тоді дані, що передаються сервером, були зазвичай у форматі XML, але в наші дні більшість сучасних додатків використовує JSON як формат для даних із сервера.
JSON є рядковим представленням даних; він виглядає як звичайний об'єкт JavaScript, але може бути використаний тільки для представлення підмножини даних, з яких складається звичайний об'єкт JavaScript. Наприклад, JSON не може представляти функції або об'єкти. Ось приклад рядка JSON, зверніть увагу, що всі властивості в лапках:
<code data-language="javascript">{ "people" : [ { "name" : "Бін", "url" : "http://benalman.com", "bio" : "Я роблю чудові сайти, корисні плагіни jQuery та граю фанк. А також керую відділом з розробки плагінів у @bocoup." }, { "name" : "Ребека", "url" : "http://rmurphey.com", "bio" : "Провідний JS-розробник у Bocoup." }, { "name" : "Джорі", "url" : "http://joryburson.com", "bio" : "Суперентузіаст відкритої веб-освіти @bocoup. Любить мистецтво, читати та підроблені вуса." } ] }
Важливо пам'ятати, що JSON є рядковим представленням об'єкта — перед роботою рядок має бути перетворений на дійсний об'єкт JavaScript. Коли ви працюєте з відповіддю JSON в XHR, то jQuery дбає про це завдання за вас, але важливо розуміти різницю між JSON-поданням об'єкта і самим об'єктом.
Якщо вам потрібно створити рядок JSON з об'єкт JavaScript або розібрати її за межами jQuery, сучасні браузери пропонують методи JSON.stringify() та JSON.parse(). Їх функціональність може бути додана у старі браузери за допомогою бібліотеки json2.js. jQuery також пропонує метод jQuery.parseJSON, який забезпечує таку ж функціональність як JSON.parse() у всіх браузерах. Однак у jQuery немає методів відповідних JSON.stringify().
Зручні методи
Якщо ми робимо простий запит і при цьому не дбаємо про обробку помилок — jQuery пропонує кілька «зручних методів», які дозволяють використовувати скорочений синтаксис. Кожен із цих методів приймає адресу, необов'язковий об'єкт даних та функцію для обробки успішного запиту.
<code data-language="javascript">$.get( '/data/people.html', function( html){ $( '#target').html( html); }); $.post( '/data/save', { name: 'Ребека' }, function( resp) { console.log( resp); });
Передача даних та робота з формами
Ми можемо надіслати дані з нашим запитом, встановивши властивість data в об'єкті конфігурації, або передавши об'єкт як другий аргумент в один із зручних методів.
Для запиту GET ці дані будуть прикріплені до рядка адреси; для запиту POST вони будуть надіслані як дані форми. jQuery пропонує корисний метод .serialize() для отримання даних форми та перетворення їх у формат рядка запиту (field1name=field1value&field2name=field2value...):
<code data-language="javascript">$ ( 'form').submit(function( event) { event.preventDefault(); var form=$( this); $.ajax({ type: 'POST', url: '/data/save', data: form .serialize(), dataType: 'json', success: function( resp) { console.log( resp); } }); });
jqXHR
$.ajax() (і пов'язані з ним зручні методи) повертає об'єкт jqXHR (jQuery XML HTTP Request), який містить безліч потужних методів. Ми можемо зробити запит через $.ajax(), а потім передати об'єкт jqXHR, що повертається, в змінну.
<code data-language="javascript">var req=$.ajax({ url: '/data/people.json', dataType: 'json' });
Ми можемо використовувати цей об'єкт, щоб до запиту прикріпити функції обробника, навіть після завершення запиту. Наприклад, ми можемо використовувати метод .then() об'єкта jqXHR, щоб прив'язати функції успіху та помилки. Метод .then() приймає одну або дві функції як аргументи — перша функція буде викликатися якщо запит успішний, друга якщо запит не вдався.
<code data-language="javascript">var success=function( resp) { $( '#target').append( '<p>людей: ' + resp.people.length + '</p>'); console.log(resp.people); }; var err=function( req, status, err) { $( '#target').append( '<p>щось пішло не так</p>'); }; req.then (success, err); req.then(function() { $( '#target').append( '<p>спрацювало</p>'); });
Ми можемо викликати .then() у запиті скільки завгодно разів, вони обслуговуються по черзі.
Якщо ми не хочемо прикріплювати функції успіху та помилки одночасно, то можемо використовувати методи .done() та .fail() для об'єкта запиту.
<code data-language="javascript"> req.done (success); req.fail( err);
Якщо ми хочемо прикріпити функцію обробника, яка виконується при успіху або невдачі, то можемо використовувати метод .always() для об'єкта запиту.
<code data-language="javascript">req.always(function() { $( '#target') .append( '<p>так чи інакше, але завершено</p>'); $.ajax</span> для отримання даних з іншого домену, а їх запит не вдається. Наприклад, ви можете спробувати отримати дані зі сторонніх API і виявити, що запит постійно зазнає невдачі.</p> <p>Як виявилося, з міркувань безпеки XHR для інших доменів блокується браузером. Тим не менш, деякі сторонні API дають відповідь у форматі JSONP (JSON with Padding), який дозволяє використовувати дані, навіть якщо вони розміщені на іншому сервері. JSONP не зовсім AJAX — але ближче, ніж використання функціональності XHR у браузері це дійсно працює шляхом вставки тега <span class="tag"><script></span> на сторінці, яка містить запитані дані. Незважаючи на це, jQuery дозволяє зробити запит JSONP з <span class="var">$.ajax()</span>, вказавши <span class="var">jsonp</span> як <span class="var">dataType</span> в об'єкті конфігурації.</p> <pre><code data-language="javascript">$.ajax({ url: '/data/search.jsonp', data: { q: 'a ' }, dataType: 'jsonp', success: function( resp) { $( '#target').html( 'Результати: ' + resp.results.length); } });
API, які пропонує JSONP, вказують ім'я параметра обробника для використання у рядку запиту. Як правило, це ім'я callback і його використовує jQuery за замовчуванням. Тим не менш, ви можете перейменувати його, вказавши властивість jsonp в об'єкті конфігурації, що передається в $.ajax().
Ви також можете використовувати зручний метод $.getJSON() щоб зробити запит JSONP. Якщо адреса включає callback=? або аналогічне, то jQuery буде розглядати його як запит JSONP.
<code data-language="javascript">$.getJSON( '/data/search.jsonp?q=a&callback=?' , function( resp) { $( '#target').html( 'Результати: ' + resp.results.length); });
CORS (cross-origin resource sharing) — ще один варіант для міждоменних запитів. Проте він не підтримується в старих браузерах і для роботи потрібні налаштування на стороні сервера та маніпуляція із заголовками XHR.