Навіщо використовувати AJAX, коли WebSockets доступний?


203

Я вже деякий час використовую WebSockets, я вирішив створити інструмент управління Agile для мого останнього року в університеті з використанням сервера Node та WebSockets. Я виявив, що використання WebSockets забезпечило 624% збільшення кількості запитів за секунду, яку моя обробка може обробити.

Однак, починаючи проект, я читав лазівки безпеки та деякі браузери, які вирішили відключити WebSockets за замовчуванням ..

Це призводить мене до питання:

Навіщо використовувати AJAX, коли WebSockets, здається, виконує таку велику роботу, знижуючи затримку та накладні ресурси, чи є щось, що AJAX робить краще, ніж WebSockets?


2
Ось список двигунів, які підтримують веб-розетки. en.wikipedia.org/wiki/…
Данте

Відповіді:


209

WebSockets не призначений замінити AJAX і не є строго навіть заміною Comet / long-опитування (хоча є багато випадків, коли це має сенс).

Мета WebSockets - забезпечити двосторонній, двонаправлений, повнодуплексний та тривалий зв’язок між браузером та сервером. WebSockets відкриває нові домени для браузерних додатків, які не були реально можливі за допомогою HTTP та AJAX (інтерактивні ігри, динамічні потоки медіа, з'єднання з існуючими мережевими протоколами тощо).

Однак, безумовно, існує збіг між WebSockets та AJAX / Comet. Наприклад, коли браузер хоче отримувати сповіщення про події сервера (тобто натискання), то, наприклад, методи Comet і WebSockets, безумовно, є обома життєздатними варіантами. Якщо вашій програмі потрібні поштові події з низькою затримкою, це може стати фактором на користь WebSockets. З іншого боку, якщо вам потрібно співіснувати з існуючими фреймворками та розгорнутими технологіями (OAuth, RESTful API, проксі-сервери, балансири навантаження), то це було б фактором на користь методів Comet (поки що).

Якщо вам не потрібні конкретні переваги, які надає WebSockets, то, мабуть, краща ідея дотримуватися існуючих методів, таких як AJAX і Comet, оскільки це дозволяє повторно використовувати та інтегруватись з величезною існуючою екосистемою інструментів, технологій, механізмів безпеки. , бази знань (тобто набагато більше людей, що знаходяться в стаковерху, знають HTTP / Ajax / Comet, ніж WebSockets) тощо.

З іншого боку, якщо ви створюєте нову програму, яка просто не працює добре в межах затримок і обмежень підключення HTTP / Ajax / Comet, тоді подумайте про використання WebSockets.

Також деякі відповіді вказують на те, що однією з недоліків WebSockets є обмежена / змішана підтримка сервера та браузера. Дозвольте мені трохи розповсюдити це. Хоча iOS (iPhone, iPad) все ще підтримує старіший протокол (Hixie), більшість серверів WebSockets підтримують як Hixie, так і HyBi / IETF 6455 версію. Більшість інших платформ (якщо вони ще не мають вбудованої підтримки) можуть отримати підтримку WebSockets через web-socket-js (Flash-поліфайли). Це охоплює переважну більшість користувачів Інтернету. Крім того, якщо ви використовуєте Node для серверного сервера, тоді розгляньте можливість використання Socket.IO, який включає web-socket-js як резервний, і якщо навіть такий недоступний (або відключений), він перейде до використання будь-якої техніки Comet доступний для даного браузера.

Оновлення : iOS 6 тепер підтримує поточний стандарт HyBi / IETF 6455.


37
І ось на зорі 2014 року WebSockets - це практично стандарт (RFC 6455), і лише Opera mini не підтримує це.
Дірк Бестер

4
Правда, Opera Mini це не підтримує, але більш бентежною є відсутність підтримки браузера Android, що робить трохи складнішим використання у програмах на основі веб-перегляду (Cordova PhoneGap)
Miles M.

2
@kanaka, Якщо вони обоє роблять великі файли однаково добре, то чому б просто не надсилати все через веб-сокети? Навіщо турбувати відхилення сторінок / даних, коли все можна надсилати через WebSockets? (Припустимо, це вже 2020 рік, і всі браузери мають підтримку WebSockets)
Pacerier

3
@Pacerier повна відповідь була б довгою, але вона в основному зводиться до того, що ви намагаєтесь повторно реалізувати речі, які браузер уже добре працює (кешування, безпека, паралелізм, обробка помилок тощо). Що стосується продуктивності, хоча швидкість передачі великого файлу з нуля була б схожа, у браузерів було багато років, щоб тонко настроїти кешування веб-контенту (значна частина цього стосується запитів AJAX), тому на практиці перехід з AJAX на WebSockets навряд чи забезпечить багато вигода для існуючої функціональності. Але для двоспрямованого спілкування з низькою затримкою це величезна виграш.
канака

5
Вибачте, але для мене це не відповідає на питання. В основному це просто говорить про те, що вони не призначені замінювати один одного і що WS не підтримується повністю (це зараз). Це не відповідає чому ви віддаєте перевагу AJAX над веб-розеткою? Візьмемо для прикладу розбрат. Discord використовує WS для передачі повідомлень та подій з сервера до клієнтів, тим часом він використовує HTTP-запити від клієнта на сервер (надсилати повідомлення, запити даних тощо). Я прийшов до цього питання, щоб насправді отримати відповідь, чому ви це зробите. Чи є якась технічна причина, чому ви поставите AJAX над відкритим WS-з'єднанням?
Шарлотта Дунуа

63

Вперед до грудня 2017 року веб-розетки підтримуються (практично) кожним браузером, і їх використання дуже поширене.

Однак це не означає, що Websockets вдалося замінити AJAX, принаймні не повністю, тим більше, що адаптація HTTP / 2 зростає.

Коротка відповідь полягає в тому, що AJAX як і раніше чудово підходить для більшості програм REST, навіть при використанні Websockets. Але Бог в деталях, так що ...:

AJAX для опитування?

Використання AJAX для опитування (або тривалого опитування) вимирає (і повинно бути), але воно все ще залишається у використанні з двох вагомих причин (головним чином для менших веб-додатків):

  1. Для багатьох розробників AJAX простіше кодувати, особливо якщо мова йде про кодування та проектування бекенда.

  2. Завдяки HTTP / 2 було ліквідовано найвищі витрати, пов'язані з AJAX (встановлення нового з'єднання), що дозволило дзвінкам AJAX бути досить ефективними, особливо для розміщення та завантаження даних.

Однак натиск Websocket набагато перевершує AJAX (не потрібно повторно аутентифікувати чи повторно надсилати заголовки, немає необхідності в зворотній смузі "без даних" тощо) ". Про це неодноразово обговорювали .

AJAX для відпустки?

Краще використовувати для AJAX дзвінки API REST. Це використання спрощує базу коду і запобігає блокуванню з’єднання Websocket (особливо при завантаженні даних середнього розміру).

Є ряд вагомих причин віддати перевагу AJAX для дзвінків REST API та завантаження даних:

  1. API AJAX був практично розроблений для дзвінків REST API, і це чудово підходить.

  2. REST-дзвінки та завантаження за допомогою AJAX значно простіше кодувати, як на клієнті, так і на сервері.

  3. Зі збільшенням корисної навантаження даних з'єднання Websocket можуть заблокуватися, якщо не буде закодована логіка фрагментації / мультиплексування.

    Якщо завантаження виконується в одному дзвінку Websocket send, воно може блокувати потік Websocket, поки завантаження не закінчиться. Це знизить продуктивність, особливо на повільних клієнтах.

Звичайний дизайн використовує невеликі bidi-повідомлення, передані через Websockets, тоді як REST та завантаження даних (клієнт на сервер) сприяють простоті використання AJAX, щоб запобігти блокуванню Websocket.

Однак у великих проектах гнучкість, пропонована Websockets, і баланс між складністю коду та управління ресурсами дозволять змінити баланс на користь Websockets.

Наприклад, завантаження на основі Websocket може запропонувати можливість відновити великі завантаження після відключення та відновлення зв'язку (пам’ятаєте, який фільм на 5 Гб ви хотіли завантажити?).

За допомогою кодування логіки фрагментації завантаження легко відновити перерване завантаження (важка частина кодувала річ).

Що з HTTP / 2 push?

Ймовірно, слід додати, що функція push HTTP / 2 не замінює (і, мабуть, не може) замінити Websockets.

Про це йшлося тут раніше, але достатньо згадати, що одне з'єднання HTTP / 2 обслуговує весь браузер (усі вкладки / вікна), тому дані, що надсилаються HTTP / 2, не знають, до якої вкладки / вікна належить, виключаючи його здатність замінювати здатність Websocket передавати дані безпосередньо на певну вкладку / вікно браузера.

Хоча веб-розетки чудово підходять для невеликих двонаправлених передач даних, AJAX все ж має ряд переваг - особливо, якщо враховувати великі корисні навантаження (завантаження тощо).

А безпека?

Ну, загалом, чим більше довіри та контролю пропонується програмісту, тим потужніший інструмент ... і тим більше проблем з безпекою, які повзають.

AJAX від природи мав би перевагу, оскільки його безпека вбудована в код браузера (що іноді викликає сумніви, але він все ще є).

З іншого боку, виклики AJAX сприйнятливіші до атак "людина в середині", тоді як проблеми безпеки Websockets - це помилки в коді програми, який вніс недолік безпеки (зазвичай логіка аутентифікації бекендера - це їх ви знайдете).

Особисто я не вважаю це великою різницею, якщо що-небудь, я думаю, Websockets трохи краще, особливо коли ви знаєте, що ви робите.

Моя скромна думка

IMHO, я б використовував Websockets для всього, крім викликів REST API. Великі завантаження даних я б фрагментував і надсилав через Websockets, коли це можливо.

Опитування, IMHO, повинно бути поза законом, вартість мережевого трафіку жахлива, а Websocket push досить простий для управління навіть для нових розробників.


2
Невелика граматична помилка "якщо щось я річ ..." подумайте 😀
spottedmahn

2
@spottedmahn - Дякую! Я думаю, що це трапляється, я використовую свій редактор коду для підготовки тексту 🙃
Myst

1
Вибачте, я був відсутній, коли закінчився термін щедрості. Погане планування з мого боку. Я встановив ще одну винагороду, яку я присуджую вам після закінчення 23 годин.
Дункан Джонс

@Myst дякую за це чудове пояснення. Що б ви хотіли для живих сповіщень, таких як fb / stackoverflow? Я розробляю веб-сервіси RestFull для свого веб-додатку, але дуже заплутався, що я повинен використовувати для функції сповіщень? AJAX або WebSockets?
TheCoder

@puspen сповіщення (IMHO) чудово підходить для Websockets. Є багато рішень, які слід прийняти, коли ви розробляєте логіку повторного підключення та офлайн-черги сповіщень, але фактичне сповіщення є простим кодуванням та виконанням за допомогою веб-розеток.
Myst

18

На додаток до проблем зі старими браузерами (включаючи IE9, оскільки WebSockets підтримуватимуться починаючи з IE10), все ще існують великі проблеми з мережевими посередниками, які ще не підтримують WebSockets, включаючи прозорі проксі, зворотні проксі-сервери та балансири завантаження. Є деякі мобільні оператори, які повністю блокують трафік WebSocket (тобто після команди HTTP UPGRADE).

З плином років WebSockets будуть все більше підтримуватися, але тим часом ви завжди повинні мати на основі HTTP запасний метод для надсилання даних у браузери.


На щастя, більшість фреймворків WebSocket підтримують згадані резервні копії, включаючи використання Flash для сокетів. Socketn.IO і SignalR - це гідні рамки ... хоча ви дійсно обмежені, як ви вже згадуєте, через проксі-сервери та балансири навантаження. На щастя, і Node.JS, і наступний IIS виконують гідну роботу і з цією роллю.
Tracker1

Цікаво: які оператори блокують WebSocket на порт 80? Який блок захищений WebSocket (WSS) на порту 443? Останнє передбачає вимушені, прозорі веб-проксі-сервери MITM .. ніколи цього не бачили в загальнодоступних мережах (лише корпоративних), оскільки це вимагає встановлення нових веб-серверів CA в браузери.
оберстет

Наприклад, на даний момент Vodafone Italy блокує WS на порт 80, але дозволяє WSS на порт 443. Ви можете протестувати будь-якого оператора через нашу домашню сторінку, до якої ви можете отримати доступ як у HTTP, так і в HTTPS. Він намагається WebSockets і повертається до HTTP, якщо вони заблоковані. Використовуйте цю URL-адресу, щоб відобразити віджет посередині, який повідомляє про поточний транспорт: lightstreamer.com/?s
Алессандро Аліноне

17

Більшість скарг, які я читав про веб-розетки та безпеку, є від постачальників засобів безпеки веб-браузера та засобів захисту брандмауера. Проблема полягає в тому, що вони не знають, як зробити аналіз безпеки трафіку веб-сокетів, оскільки після того, як він здійснив оновлення з HTTP до двійкового протоколу websocket, вміст пакету та його значення залежить від програми (залежно від програми, яку ви програмуєте). Це, очевидно, логічний кошмар для цих компаній, життєдіяльність яких ґрунтується на аналізі та класифікації всього вашого інтернет-трафіку. :)


11

WebSockets не працюють у старих веб-браузерах, а ті, що підтримують його, часто мають різні варіанти реалізації. Це майже єдина вагома причина, чому вони не використовуються весь час замість AJAX.


8
Кращою причиною є те, що запит AJAX - це звичайний HTTP-запит, що означає, що він може отримувати ресурси HTTP; WebSockets не може цього зробити.
Ден Д.

@Dan Що якщо, наприклад, файли зображень надсилаються як base64, CSS як текст, JavaScript також як текст, а потім додаються до документа? Це було б правдоподібно?
Джек

@DanD. +1, я погоджуюсь, я думаю, я підходив до питання більше з контексту швидкого потокового передавання даних, як у прикладі запитання, але це, безумовно, правильно.
jli

@Dan D - іноді ви не хочете, щоб усі ці лайно переходили лінію, такі як файли cookie та заголовки ...
vsync

8
@DanD., HTTP та WebSocket - це два різних протоколи. Звичайно, ми не можемо запитувати ресурси HTTP за допомогою протоколу WebSocket з тієї ж причини, що ми не можемо запитувати ресурси WebSocket за допомогою протоколу HTTP! Це не означає, що клієнт не може вимагати html та / або файли зображень, що надсилаються через протокол Websocket.
Печер'є

2

Я не думаю, що ми можемо зробити чітке порівняння Websockets та HTTP, оскільки вони не є конкурентами і не вирішують однакових проблем.

Веб-розетки є прекрасним вибором для обробки тривалої двонаправленої потокової передачі даних майже в режимі реального часу, тоді як REST чудово підходить для випадкових комунікацій. Використання веб-розеток - це вагома інвестиція, отже, це надмірна кількість випадкових з'єднань.

Ви можете виявити, що Websockets справляються краще, коли є високі навантаження, HTTP у деяких випадках трохи швидший, оскільки він може використовувати кешування. Порівнювати REST з веб-розетками - це як порівнювати яблука з апельсинами.

Ми повинні перевірити, яке з них пропонує краще рішення для нашого застосування, яке найкраще підходить для нашого використання.


1
питання стосувалося AJAX взагалі, а не REST зокрема. Це правда, що AJAX можна використовувати для REST, але він також використовується для опитування та тривалого опитування. Хоча я згоден з вашим висновком (як ви можете сказати з моєї відповіді), я вважаю, що ваша відповідь може відображати відмінність (зауважте, що Websockets можна використовувати і для REST, хоча і не за допомогою методів HTTP).
Міст

@Myst Я згоден з вами.
Гаурав Ганді

1

Приклад відмінності між HTTP та Websockets у вигляді вкладки розміру клієнта, яка може обробляти кінцеву точку Websocket, як API REST та RESTful кінцеві точки, як Websockets на клієнті. https://github.com/mikedeshazer/sockrest Також для тих, хто намагається споживати API веб-розетки на клієнті або навпаки, як вони звикли. Libs / sockrest.js в значній мірі дає зрозуміти відмінності (а точніше, передбачається).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.