SlideShare a Scribd company logo
Ajax and Transports (in russian)
Михаил Давыдов
Разработчик JavaScript
Транспорт, ajax
3
Немного истории
•  FRAME, IFRAME – IE 3, 1996год
•  ActiveX MSXML – IE 5.5, 1998год
•  AJAX, Web 2.0 – 2005год
•  W3C XMLHttpRequest – 2006год стандарт
Кроссодоменные запросы
JSONP,
Post2HiddenIframe,
XMLHttpRequest level 2 (CORS),
Каскад фреймов или postMessage
5
JSONP
•  Когда применять
–  Запрос каких-то не очень критичных данных
–  Прием огромных объемов данных
•  Плюсы
–  Дешевый способ
–  Доступен в любом браузере
•  Минусы
–  Невозможно отследить статус ответа и ошибки, только таймауты
–  Только GET
–  Не безопасный
0+ 0+ 0+ 0+ 3+
JSONP
// 1 Готовим «Ловушку»
window.jsonFlickrFeed = function (data) {
console.log(data);
};
var serviceUrl = 'http://api.flickr.com/services/feeds' +
'/photos_public.gne?format=json&' +
'jsoncallback=jsonFlickrFeed';
// 2 Создаем скрипт
var scriptElement = document.createElement('script');
scriptElement.src = serviceUrl;
document.body.appendChild(scriptElement);
http://jsfiddle.net/ffTQL/1/
7
Post2HiddenIframe
•  Кода применять
–  Push каких-то не критичных данных
–  Отправка файлов
•  Плюсы
–  Реализация очень проста
–  Доступен в любом браузере
–  Можно отправлять файлы
–  POST, GET
•  Минусы
–  Нет возможности подтвердить получение данных сервером
0+ 0+ 0+ 0+ 3+
Post2HiddenIframe
// 1 Создаем форму
<form target="frame"
action="http://yandex.ru/"
method="post">
<input name="data"/>
<input type="submit"/>
</form>
// 2 Создаем фрейм
<iframe name="frame"></iframe>
http://jsfiddle.net/E2nge/
9
XHR2 (CORS)
•  Кода применять
–  Запрос критичных данных
–  Long Polling
•  Плюсы
–  Не отличается от XHR (IE – XDomainRequest)
–  Это не костыль
–  Можно отследить ошибки и статусы ответа
–  Простая реализация поддержки на сервере
–  DELETE, GET, HEAD, OPTIONS, POST, PUT
•  Минусы
–  Не поддерживается многими старыми браузерами
–  Может блокироваться прокси-серверами
4.0 3.5 12 4.0 10
XHR2 (CORS)
function requestFactory() {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
return xhr;
}
if (typeof XDomainRequest !== "undefined") {
return new XDomainRequest();
}
}
var xhr = requestFactory();
if (!xhr) throw new Error('CORS not supported');
xhr.open('GET', 'http://yandex.ru/', true);
xhr.send();
http://jsfiddle.net/qyjnb/
11
Каскад фреймов или postMessage
•  На самоподготовку
–  Выделите его достоинства и недостатки
–  Сравните с предыдущими методами
Real-time приложения
LongPolling через XHR,
EventSource (Server Sent Events),
WebSocket
13
LongPolling & XHR
•  Когда применять
–  Для обратной совместимости со старыми браузерами
–  Приложения где данные передаются редко
–  Вам лень писать что-то другое
•  Плюсы
–  Это работает во всех браузерах
–  Самая простая реализация
•  Минусы
–  Приходится постоянно создавать соединения
–  Для отправки данных необходимо поднимать еще одно соединение
–  Проблема с одновременными запросами
1.0 0.6 8.0 1.2 5.0
LongPolling & XHR
function poll(resource, callback) {
$.get(resource, function (e, data) {
if (callback(data)) {
poll(resource, callback);
}
});
}
poll('/echo/json/', function (data) {
console.log(data);
return Math.random() > 0.5;
});
http://jsfiddle.net/mtP2W/
15
EventSource
•  Когда применять
–  Ваш сервис большую часть времени получает данные
–  Для обратной совместимости со старыми браузерами
•  Плюсы
–  Использует HTTP протокол
–  Реализация на сервере достаточна проста
–  Может автоматически делать реконнект
–  Достаточно гибкий формат сообщений
–  1 постоянное соединение с сервером
•  Минусы
–  Может неадекватно вести себя при физическом отключении от сети
–  Может только принимать данные
–  Не поддерживается IE
–  Может блокироваться прокси-серверами
6.0 6.0 9.0 5.0 –
LongPolling & XHR
// Content-Type: text/event-stream
// Cache-Control: no-cache
if (!window.EventSource) throw new Error('No SSE');
var dataProvider = new EventSource('/echo/json/');
dataProvider.addEventListener('message', function(e) {
console.log(e.data);
}, false);
dataProvider.addEventListener('error', function(e) {
if (e.readyState == EventSource.CLOSED) {
console.log('Connection closed');
}
}, false);
http://jsfiddle.net/BvTTz/
17
WebSocket
•  Когда применять
–  Актуальность данных очень критична
–  Очень много данных передается или передаются очень часто
•  Плюсы
–  1 соединение на отправку и получение
–  Быстрый обмен данными
–  Бинарный формат
•  Минусы
–  Не HTTP
–  Сложно отлаживать
–  Может блокироваться прокси-серверами
–  6 форматов протокола
–  Поддерживается далеко не всеми веб-браузерами
14.0 11.0* 8.0 6.0 10.0
LongPolling & XHR
window.WebSocket = window.WebSocket || window.MozWebSocket;
var connection = new WebSocket('ws://echo.websocket.org');
connection.addEventListener('message', function(e) {
console.log(e.data);
}, false);
connection.addEventListener('error', function(e) {
console.log(e);
}, false);
connection.send('Hello World!');
http://jsfiddle.net/pgLQa/2/
Загрузка файлов
Post2HiddenIframe + JSONP,
XMLHttpRequest level 2 + File API,
Flash
20
Post2HiddenIframe + JSONP
•  Post2HiddenIframe – для отправки
•  JSONP – для контроля
–  Прогресс отправки
–  Результат отправки
–  Получение ссылки на файл
•  Плюсы
–  Работает везде
•  Минусы
–  Необходим контроль
–  Много дополнительных запросов
0+ 0+ 0+ 0+ 3+
Post2HiddenIframe + JSONP
<form target="frame"
action="http://yandex.ru/"
method="post"
enctype="multipart/form-data">
<input name="file" type="file"/>
</form>
<iframe name="frame"></iframe>
http://jsfiddle.net/AZmXx/2/	

$('input').change(function () {
$('form').submit();
});
$.getJSON('/echo/jsonp/?callback=?', function(e, progress) {
console.log(progress);
});
22
XHR2 + File API
•  Плюсы
–  Естественный способ без костылей
–  Только 1 запрос
–  Реализация на сервере проще чем Post2HiddenIframe + JSONP
•  Минусы
–  Не поддерживается всеми браузерами
13.0 3.6 12 5.1* 10.0*
XHR2 + File API
document.getElementById('file')
.addEventListener('change', function(e) {
var file = this.files[0];
var xhr = new XMLHttpRequest();
var formData = new FormData();
formData.append('thefile', file);
xhr.open('post', '/echo/json/', true);
xhr.setRequestHeader('Content-Type',
'multipart/form-data');
xhr.send(formData);
}, false);
http://jsfiddle.net/qnvt2/1/
24
Flash
•  На самоподготовку
–  Выделите его проблемы
–  Сравните с рассмотренными выше способами
Библиотеки и обертки
jQuery.ajax,
jQuery.serialize,
Socket.IO,
NowJS
jQuery.ajax
var globalCallback = function () {
console.log(arguments);
};
$.get('/echo/json/', globalCallback);
$.post('/echo/json/', globalCallback);
$.getJSON('/echo/json/', globalCallback);
$.getJSON('/echo/jsonp/?callback=?', globalCallback);
$.ajax('/echo/json/', {
statusCode: {
404: globalCallback
}
}).done(globalCallback);
http://jsfiddle.net/hLU92/
jQuery.serialize
<form>
<input type="text" name="a" value="1"/>
<input type="text" name="b" value="2"/>
<input type="hidden" name="c" value="3"/>
</form>
http://jsfiddle.net/Smvvr/	

$('form').submit(function() {
alert($(this).serialize());
return false;
});
Socket.IO
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
http://socket.io/	

var io = require('socket.io').listen(80); // Server
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
NowJS
var nowjs = require("now"); // Server
var everyone = nowjs.initialize(httpServer);
everyone.now.getServerInfo = function(callback){
callback("Hello World!");
}
http://nowjs.com/	

<script src="//localhost/nowjs/now.js"></script>
<script>
now.getServerInfo(function(data){
console.log(data);
});
</script>
Проблемы
Каскады протоколов,
Баги браузеров,
Прокси серверы,
Обрывы соединения,
Асинхронная модель приложения
Михаил Давыдов
Разработчик JavaScript
azproduction@yandex-team.ru
azproduction
Спасибо

More Related Content

PDF
Михаил Давыдов: Транспорт, ajax
PPT
DevConf2013: Особенности применения WebSocket на примере работы в ERP системе.
PDF
Практическое применение HTML5 в Я.Почте
PDF
Доставка данных в реальном времени.
PDF
WebSockets
PPTX
Алексей Морозов (Россия), Rambler.ru. ASP.NET в помощь хакеру и не только....
PPT
Web sockets
PPT
Eugene Lisitsky Web Sockets
Михаил Давыдов: Транспорт, ajax
DevConf2013: Особенности применения WebSocket на примере работы в ERP системе.
Практическое применение HTML5 в Я.Почте
Доставка данных в реальном времени.
WebSockets
Алексей Морозов (Россия), Rambler.ru. ASP.NET в помощь хакеру и не только....
Web sockets
Eugene Lisitsky Web Sockets

What's hot (20)

PDF
17 - Web-технологии. Real Time сообщения
PPTX
Иван Чалыкин (Россия), Digital Security. Легальный SOP Bypass. Проблемы внедр...
PPTX
Татьяна Новикова (Казахстан), ЦАРКА. Как мы мониторим Казнет с помощью WebTotem
PDF
Андрей Абакумов (Россия). Yandex.ru. Соавтор: Эльдар Заитов. Автоматизация ск...
PPTX
Everything you wanted to know about writing async, high-concurrency HTTP apps...
PDF
Стажировка-2015. Разработка. Занятие 3. Серверные Java-приложения
PPTX
PostgreSQL. Стильно. Модно. Молодёжно
PPTX
Chrome push notifications. Анатомия и разработка
PDF
05 - Web-технологии. Сетевые протоколы
PPTX
Periculum est in mora
PDF
Профилирование кода на C/C++ в *nix системах
PPTX
Шамбулов У. К. (Казахстан), ГТС. Анализ и исследование инцидентов информацион...
PDF
Семь тысяч Rps, один go
PDF
Бекэнд для push-уведомлений своими руками
PPTX
KazHackStan 2017 | Tracking
PDF
Анатомия веб сервиса (HighLoad-2014)
PDF
07 - Web-технологии. Web-сервера
PDF
06 - Web-технологии. Протокол HTTP
PDF
08 - Web-технологии. Архитектура frontend-backend
PDF
Pavel Dovbush Toster
17 - Web-технологии. Real Time сообщения
Иван Чалыкин (Россия), Digital Security. Легальный SOP Bypass. Проблемы внедр...
Татьяна Новикова (Казахстан), ЦАРКА. Как мы мониторим Казнет с помощью WebTotem
Андрей Абакумов (Россия). Yandex.ru. Соавтор: Эльдар Заитов. Автоматизация ск...
Everything you wanted to know about writing async, high-concurrency HTTP apps...
Стажировка-2015. Разработка. Занятие 3. Серверные Java-приложения
PostgreSQL. Стильно. Модно. Молодёжно
Chrome push notifications. Анатомия и разработка
05 - Web-технологии. Сетевые протоколы
Periculum est in mora
Профилирование кода на C/C++ в *nix системах
Шамбулов У. К. (Казахстан), ГТС. Анализ и исследование инцидентов информацион...
Семь тысяч Rps, один go
Бекэнд для push-уведомлений своими руками
KazHackStan 2017 | Tracking
Анатомия веб сервиса (HighLoad-2014)
07 - Web-технологии. Web-сервера
06 - Web-технологии. Протокол HTTP
08 - Web-технологии. Архитектура frontend-backend
Pavel Dovbush Toster
Ad

Viewers also liked (11)

PDF
JavaScript. OOP (in russian)
PDF
JavaScript. Loops and functions (in russian)
PDF
JavaScript. Basics (in russian)
PDF
JavaScript. Event Loop and Timers (in russian)
PDF
Dart - светлая сторона силы?
PDF
Dump-IT Загрузка и инициализация JavaScript
PDF
Components now! (in russian)
PDF
Introduction in Node.js (in russian)
PDF
JavaScript. Async (in Russian)
PDF
JavaScript. Event Model (in russian)
PDF
Components now!
JavaScript. OOP (in russian)
JavaScript. Loops and functions (in russian)
JavaScript. Basics (in russian)
JavaScript. Event Loop and Timers (in russian)
Dart - светлая сторона силы?
Dump-IT Загрузка и инициализация JavaScript
Components now! (in russian)
Introduction in Node.js (in russian)
JavaScript. Async (in Russian)
JavaScript. Event Model (in russian)
Components now!
Ad

Similar to Ajax and Transports (in russian) (20)

PDF
Михаил Давыдов — Транспорт, Ajax
PDF
Mihail davidov js-ajax
PDF
Алексей Андросов "HTML5 в Я.Почте"
PPT
Catalyst – MVC framework на Perl (RIT 2008)
PPT
Интеграция открытых технологий и взаимодействие со сторонними проектами в усл...
PPTX
Node.js введение в технологию, КПИ #ITmeetingKPI
PPT
Node.JS: возможности для РНР-разработчика
PDF
Phalcon - самый быстрый PHP Framework
PDF
JavaScript Базовый. Занятие 08.
PDF
Алексей Андросов "HTML5 в Я.Почте (WebSocket, localStorage, Cross-site XHR)"
PDF
Aleksey Androsov
PDF
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
PPT
Eugene Lisitsky Web Sockets
PPTX
Пост-эксплуатация веб-приложений в тестах на проникновение
PPTX
Мировые информационные ресурсы. Лекция 5
PDF
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
PPT
Web весна 2012 лекция 9
PPTX
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tips
PPTX
Waf.js: как защищать веб-приложения с использованием JavaScript
PPTX
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Михаил Давыдов — Транспорт, Ajax
Mihail davidov js-ajax
Алексей Андросов "HTML5 в Я.Почте"
Catalyst – MVC framework на Perl (RIT 2008)
Интеграция открытых технологий и взаимодействие со сторонними проектами в усл...
Node.js введение в технологию, КПИ #ITmeetingKPI
Node.JS: возможности для РНР-разработчика
Phalcon - самый быстрый PHP Framework
JavaScript Базовый. Занятие 08.
Алексей Андросов "HTML5 в Я.Почте (WebSocket, localStorage, Cross-site XHR)"
Aleksey Androsov
Алексей Андросов "Яндекс.Почта: архитектура фронтенда как она есть"
Eugene Lisitsky Web Sockets
Пост-эксплуатация веб-приложений в тестах на проникновение
Мировые информационные ресурсы. Лекция 5
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Web весна 2012 лекция 9
Костянтин Чаус — Monitoring of huge Drupal site. Tools and tips
Waf.js: как защищать веб-приложения с использованием JavaScript
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...

Ajax and Transports (in russian)

  • 3. 3 Немного истории •  FRAME, IFRAME – IE 3, 1996год •  ActiveX MSXML – IE 5.5, 1998год •  AJAX, Web 2.0 – 2005год •  W3C XMLHttpRequest – 2006год стандарт
  • 5. 5 JSONP •  Когда применять –  Запрос каких-то не очень критичных данных –  Прием огромных объемов данных •  Плюсы –  Дешевый способ –  Доступен в любом браузере •  Минусы –  Невозможно отследить статус ответа и ошибки, только таймауты –  Только GET –  Не безопасный 0+ 0+ 0+ 0+ 3+
  • 6. JSONP // 1 Готовим «Ловушку» window.jsonFlickrFeed = function (data) { console.log(data); }; var serviceUrl = 'http://api.flickr.com/services/feeds' + '/photos_public.gne?format=json&amp;' + 'jsoncallback=jsonFlickrFeed'; // 2 Создаем скрипт var scriptElement = document.createElement('script'); scriptElement.src = serviceUrl; document.body.appendChild(scriptElement); http://jsfiddle.net/ffTQL/1/
  • 7. 7 Post2HiddenIframe •  Кода применять –  Push каких-то не критичных данных –  Отправка файлов •  Плюсы –  Реализация очень проста –  Доступен в любом браузере –  Можно отправлять файлы –  POST, GET •  Минусы –  Нет возможности подтвердить получение данных сервером 0+ 0+ 0+ 0+ 3+
  • 8. Post2HiddenIframe // 1 Создаем форму <form target="frame" action="http://yandex.ru/" method="post"> <input name="data"/> <input type="submit"/> </form> // 2 Создаем фрейм <iframe name="frame"></iframe> http://jsfiddle.net/E2nge/
  • 9. 9 XHR2 (CORS) •  Кода применять –  Запрос критичных данных –  Long Polling •  Плюсы –  Не отличается от XHR (IE – XDomainRequest) –  Это не костыль –  Можно отследить ошибки и статусы ответа –  Простая реализация поддержки на сервере –  DELETE, GET, HEAD, OPTIONS, POST, PUT •  Минусы –  Не поддерживается многими старыми браузерами –  Может блокироваться прокси-серверами 4.0 3.5 12 4.0 10
  • 10. XHR2 (CORS) function requestFactory() { var xhr = new XMLHttpRequest(); if ("withCredentials" in xhr) { return xhr; } if (typeof XDomainRequest !== "undefined") { return new XDomainRequest(); } } var xhr = requestFactory(); if (!xhr) throw new Error('CORS not supported'); xhr.open('GET', 'http://yandex.ru/', true); xhr.send(); http://jsfiddle.net/qyjnb/
  • 11. 11 Каскад фреймов или postMessage •  На самоподготовку –  Выделите его достоинства и недостатки –  Сравните с предыдущими методами
  • 12. Real-time приложения LongPolling через XHR, EventSource (Server Sent Events), WebSocket
  • 13. 13 LongPolling & XHR •  Когда применять –  Для обратной совместимости со старыми браузерами –  Приложения где данные передаются редко –  Вам лень писать что-то другое •  Плюсы –  Это работает во всех браузерах –  Самая простая реализация •  Минусы –  Приходится постоянно создавать соединения –  Для отправки данных необходимо поднимать еще одно соединение –  Проблема с одновременными запросами 1.0 0.6 8.0 1.2 5.0
  • 14. LongPolling & XHR function poll(resource, callback) { $.get(resource, function (e, data) { if (callback(data)) { poll(resource, callback); } }); } poll('/echo/json/', function (data) { console.log(data); return Math.random() > 0.5; }); http://jsfiddle.net/mtP2W/
  • 15. 15 EventSource •  Когда применять –  Ваш сервис большую часть времени получает данные –  Для обратной совместимости со старыми браузерами •  Плюсы –  Использует HTTP протокол –  Реализация на сервере достаточна проста –  Может автоматически делать реконнект –  Достаточно гибкий формат сообщений –  1 постоянное соединение с сервером •  Минусы –  Может неадекватно вести себя при физическом отключении от сети –  Может только принимать данные –  Не поддерживается IE –  Может блокироваться прокси-серверами 6.0 6.0 9.0 5.0 –
  • 16. LongPolling & XHR // Content-Type: text/event-stream // Cache-Control: no-cache if (!window.EventSource) throw new Error('No SSE'); var dataProvider = new EventSource('/echo/json/'); dataProvider.addEventListener('message', function(e) { console.log(e.data); }, false); dataProvider.addEventListener('error', function(e) { if (e.readyState == EventSource.CLOSED) { console.log('Connection closed'); } }, false); http://jsfiddle.net/BvTTz/
  • 17. 17 WebSocket •  Когда применять –  Актуальность данных очень критична –  Очень много данных передается или передаются очень часто •  Плюсы –  1 соединение на отправку и получение –  Быстрый обмен данными –  Бинарный формат •  Минусы –  Не HTTP –  Сложно отлаживать –  Может блокироваться прокси-серверами –  6 форматов протокола –  Поддерживается далеко не всеми веб-браузерами 14.0 11.0* 8.0 6.0 10.0
  • 18. LongPolling & XHR window.WebSocket = window.WebSocket || window.MozWebSocket; var connection = new WebSocket('ws://echo.websocket.org'); connection.addEventListener('message', function(e) { console.log(e.data); }, false); connection.addEventListener('error', function(e) { console.log(e); }, false); connection.send('Hello World!'); http://jsfiddle.net/pgLQa/2/
  • 19. Загрузка файлов Post2HiddenIframe + JSONP, XMLHttpRequest level 2 + File API, Flash
  • 20. 20 Post2HiddenIframe + JSONP •  Post2HiddenIframe – для отправки •  JSONP – для контроля –  Прогресс отправки –  Результат отправки –  Получение ссылки на файл •  Плюсы –  Работает везде •  Минусы –  Необходим контроль –  Много дополнительных запросов 0+ 0+ 0+ 0+ 3+
  • 21. Post2HiddenIframe + JSONP <form target="frame" action="http://yandex.ru/" method="post" enctype="multipart/form-data"> <input name="file" type="file"/> </form> <iframe name="frame"></iframe> http://jsfiddle.net/AZmXx/2/ $('input').change(function () { $('form').submit(); }); $.getJSON('/echo/jsonp/?callback=?', function(e, progress) { console.log(progress); });
  • 22. 22 XHR2 + File API •  Плюсы –  Естественный способ без костылей –  Только 1 запрос –  Реализация на сервере проще чем Post2HiddenIframe + JSONP •  Минусы –  Не поддерживается всеми браузерами 13.0 3.6 12 5.1* 10.0*
  • 23. XHR2 + File API document.getElementById('file') .addEventListener('change', function(e) { var file = this.files[0]; var xhr = new XMLHttpRequest(); var formData = new FormData(); formData.append('thefile', file); xhr.open('post', '/echo/json/', true); xhr.setRequestHeader('Content-Type', 'multipart/form-data'); xhr.send(formData); }, false); http://jsfiddle.net/qnvt2/1/
  • 24. 24 Flash •  На самоподготовку –  Выделите его проблемы –  Сравните с рассмотренными выше способами
  • 26. jQuery.ajax var globalCallback = function () { console.log(arguments); }; $.get('/echo/json/', globalCallback); $.post('/echo/json/', globalCallback); $.getJSON('/echo/json/', globalCallback); $.getJSON('/echo/jsonp/?callback=?', globalCallback); $.ajax('/echo/json/', { statusCode: { 404: globalCallback } }).done(globalCallback); http://jsfiddle.net/hLU92/
  • 27. jQuery.serialize <form> <input type="text" name="a" value="1"/> <input type="text" name="b" value="2"/> <input type="hidden" name="c" value="3"/> </form> http://jsfiddle.net/Smvvr/ $('form').submit(function() { alert($(this).serialize()); return false; });
  • 28. Socket.IO var socket = io.connect('http://localhost'); socket.on('news', function (data) { console.log(data); socket.emit('my other event', { my: 'data' }); }); http://socket.io/ var io = require('socket.io').listen(80); // Server io.sockets.on('connection', function (socket) { socket.emit('news', { hello: 'world' }); socket.on('my other event', function (data) { console.log(data); }); });
  • 29. NowJS var nowjs = require("now"); // Server var everyone = nowjs.initialize(httpServer); everyone.now.getServerInfo = function(callback){ callback("Hello World!"); } http://nowjs.com/ <script src="//localhost/nowjs/now.js"></script> <script> now.getServerInfo(function(data){ console.log(data); }); </script>
  • 30. Проблемы Каскады протоколов, Баги браузеров, Прокси серверы, Обрывы соединения, Асинхронная модель приложения