Tại sao sử dụng AJAX khi WebSockets có sẵn?


203

Tôi đã sử dụng WebSockets được một thời gian rồi, tôi đã chọn tạo một công cụ quản lý dự án Agile cho dự án năm cuối của tôi tại Đại học sử dụng máy chủ Node và WebSockets. Tôi thấy rằng sử dụng WebSockets cung cấp số lượng yêu cầu tăng lên 624% mỗi giây, ứng dụng của tôi có thể xử lý.

Tuy nhiên, kể từ khi bắt đầu dự án, tôi đã đọc các lỗ hổng bảo mật và một số trình duyệt chọn tắt WebSockets theo mặc định ..

Điều này dẫn tôi đến câu hỏi:

Tại sao sử dụng AJAX khi WebSockets dường như thực hiện một công việc tuyệt vời như vậy để giảm độ trễ và chi phí tài nguyên, có điều gì AJAX làm tốt hơn WebSockets không?


2
Đây là danh sách các công cụ hỗ trợ ổ cắm web. vi.wikipedia.org/wiki/ Kẻ
Dante

Câu trả lời:


209

WebSockets không có ý định thay thế AJAX và thậm chí không hoàn toàn thay thế cho Comet / cuộc thăm dò dài (mặc dù có nhiều trường hợp điều này có ý nghĩa).

Mục đích của WebSockets là cung cấp kết nối có độ trễ thấp, hai chiều, song công hoàn toàn và hoạt động lâu dài giữa trình duyệt và máy chủ. WebSockets mở ra các miền ứng dụng mới cho các ứng dụng trình duyệt không thực sự có thể sử dụng HTTP và AJAX (trò chơi tương tác, luồng phương tiện động, kết nối với các giao thức mạng hiện có, v.v.).

Tuy nhiên, chắc chắn có sự trùng lặp về mục đích giữa WebSockets và AJAX / Comet. Ví dụ: khi trình duyệt muốn được thông báo về các sự kiện máy chủ (tức là đẩy) thì các kỹ thuật Comet và WebSockets chắc chắn là cả hai tùy chọn khả thi. Nếu ứng dụng của bạn cần các sự kiện đẩy có độ trễ thấp thì đây sẽ là một yếu tố có lợi cho WebSockets. Mặt khác, nếu bạn cần cùng tồn tại với các khung công nghệ hiện có và các công nghệ được triển khai (OAuth, API RESTful, proxy, cân bằng tải) thì đây sẽ là một yếu tố có lợi cho các kỹ thuật Comet (hiện tại).

Nếu bạn không cần những lợi ích cụ thể mà WebSockets cung cấp, thì có lẽ nên sử dụng các kỹ thuật hiện có như AJAX và Comet vì điều này cho phép bạn sử dụng lại và tích hợp với một hệ sinh thái lớn về công cụ, công nghệ, cơ chế bảo mật , các cơ sở kiến ​​thức (nghĩa là nhiều người trên stackoverflow biết HTTP / Ajax / Comet hơn WebSockets), v.v.

Mặt khác, nếu bạn đang tạo một ứng dụng mới không hoạt động tốt trong các ràng buộc về độ trễ và kết nối của HTTP / Ajax / Comet, thì hãy xem xét sử dụng WebSockets.

Ngoài ra, một số câu trả lời chỉ ra rằng một trong những nhược điểm của WebSockets là hỗ trợ trình duyệt và máy chủ bị giới hạn / hỗn hợp. Hãy để tôi khuếch tán điều đó một chút. Trong khi iOS (iPhone, iPad) vẫn hỗ trợ giao thức cũ (Hixie), hầu hết các máy chủ WebSockets đều hỗ trợ cả phiên bản Hixie và HyBi / IETF 6455 . Hầu hết các nền tảng khác (nếu chúng chưa có hỗ trợ tích hợp) có thể nhận hỗ trợ WebSockets thông qua web-socket-js (Polyfill dựa trên Flash). Điều này bao gồm phần lớn người dùng web. Ngoài ra, nếu bạn đang sử dụng Node cho phụ trợ máy chủ, thì hãy xem xét sử dụng Socket.IO bao gồm web-socket-js như một dự phòng và nếu thậm chí không có sẵn (hoặc bị vô hiệu hóa) thì nó sẽ quay trở lại sử dụng bất kỳ kỹ thuật Comet nào có sẵn cho trình duyệt nhất định.

Cập nhật : iOS 6 hiện hỗ trợ chuẩn HyBi / IETF 6455 hiện tại.


37
Và bây giờ, vào buổi bình minh năm 2014, WebSockets thực tế là một tiêu chuẩn (RFC 6455) và chỉ Opera mini không hỗ trợ nó.
Dirk Bester

4
Thật vậy, Opera Mini không hỗ trợ nhưng điều đáng xấu hổ hơn là sự thiếu hỗ trợ của trình duyệt Android khiến việc sử dụng ứng dụng dựa trên webview trở nên phức tạp hơn một chút (Cordova PhoneGap)
Miles M.

2
@kanaka, Nếu cả hai đều làm các tệp lớn tốt như nhau, thì tại sao không đơn giản gửi mọi thứ qua websockets? Tại sao phải bận tâm đến các trang / dữ liệu khi mọi thứ có thể được gửi qua WebSockets? (Giả sử đã đến năm 2020 và tất cả các trình duyệt đều hỗ trợ WebSockets)
Pacerier

3
@Pacerier một câu trả lời hoàn chỉnh sẽ rất dài, nhưng về cơ bản, nó hiểu rõ rằng bạn đang cố gắng thực hiện lại những thứ mà trình duyệt đã làm tốt (bộ nhớ đệm, bảo mật, xử lý song song, xử lý lỗi, v.v.). Về hiệu suất, mặc dù tốc độ truyền tệp lớn từ đầu đến cuối sẽ tương tự nhau, nhưng các trình duyệt đã có nhiều năm để tinh chỉnh bộ nhớ đệm của nội dung web (phần lớn áp dụng cho các yêu cầu AJAX) vì vậy trên thực tế, việc chuyển từ AJAX sang WebSockets không thể cung cấp nhiều lợi ích cho chức năng hiện có. Nhưng đối với truyền thông hai chiều có độ trễ thấp thì đó là một chiến thắng rất lớn.
kanaka

5
Tôi xin lỗi nhưng đối với tôi nó không trả lời câu hỏi. Về cơ bản, nó chỉ nói rằng chúng không có nghĩa là thay thế nhau và WS không được hỗ trợ đầy đủ (hiện tại). Nó không trả lời tại sao bạn thích AJAX hơn websocket? Hãy lấy Discord làm ví dụ. Discord sử dụng WS để đẩy các thông điệp và sự kiện từ máy chủ đến máy khách, trong khi đó, nó sử dụng các yêu cầu HTTP từ máy khách đến máy chủ (gửi tin nhắn, dữ liệu yêu cầu, v.v.). Tôi đã đến câu hỏi này để thực sự có được câu trả lời tại sao bạn sẽ làm điều đó. Có một số lý do kỹ thuật tại sao bạn lại đặt AJAX trên kết nối WS mở không?
Charlotte Dunois

63

Chuyển nhanh đến tháng 12 năm 2017, Websockets được hỗ trợ bởi (thực tế) mọi trình duyệt và việc sử dụng chúng là rất phổ biến.

Tuy nhiên, điều này không có nghĩa là Websockets được quản lý để thay thế AJAX, ít nhất là không hoàn toàn, đặc biệt là khi sự thích ứng HTTP / 2 đang gia tăng.

Câu trả lời ngắn gọn là AJAX vẫn tuyệt vời cho hầu hết các ứng dụng REST, ngay cả khi sử dụng Websockets. Nhưng thần có trong chi tiết, nên ...:

AJAX để bỏ phiếu?

Việc sử dụng AJAX để bỏ phiếu (hoặc bỏ phiếu dài) sắp hết (và nó nên như vậy), nhưng nó vẫn được sử dụng vì hai lý do chính đáng (chủ yếu cho các ứng dụng web nhỏ hơn):

  1. Đối với nhiều nhà phát triển, AJAX dễ viết mã hơn, đặc biệt là khi nói về mã hóa và thiết kế phụ trợ.

  2. Với HTTP / 2, chi phí cao nhất liên quan đến AJAX (thiết lập kết nối mới) đã được loại bỏ, cho phép các cuộc gọi AJAX khá hiệu quả, đặc biệt là để đăng và tải lên dữ liệu.

Tuy nhiên, tính năng đẩy Websocket vượt trội hơn nhiều so với AJAX (không cần xác thực lại hoặc gửi lại tiêu đề, không cần vòng tròn "không có dữ liệu", v.v.). Điều này đã được thảo luận một số lần.

AJAX cho REST?

Sử dụng tốt hơn cho AJAX là các lệnh gọi API REST. Việc sử dụng này giúp đơn giản hóa cơ sở mã và ngăn chặn kết nối Websocket (đặc biệt là khi tải lên dữ liệu cỡ trung bình).

Có một số lý do thuyết phục để thích AJAX cho các cuộc gọi API REST và tải lên dữ liệu:

  1. API AJAX thực tế được thiết kế cho các lệnh gọi API REST và nó rất phù hợp.

  2. Các cuộc gọi REST và tải lên bằng AJAX dễ dàng hơn để mã hóa, cả trên máy khách và phụ trợ.

  3. Khi tải trọng dữ liệu tăng lên, các kết nối Websocket có thể bị chặn trừ khi logic phân mảnh / ghép kênh thông điệp được mã hóa.

    Nếu quá trình tải lên được thực hiện trong một sendcuộc gọi Websocket duy nhất , nó có thể chặn luồng Websocket cho đến khi quá trình tải lên kết thúc. Điều này sẽ làm giảm hiệu suất, đặc biệt là trên các máy khách chậm hơn.

Một thiết kế phổ biến sử dụng các thông điệp giá thầu nhỏ được chuyển qua Websockets trong khi REST và tải lên dữ liệu (máy khách đến máy chủ) tận dụng tính dễ sử dụng của AJAX để ngăn chặn Websocket chặn.

Tuy nhiên, trên các dự án lớn hơn, tính linh hoạt được cung cấp bởi Websockets và sự cân bằng giữa độ phức tạp của mã và quản lý tài nguyên sẽ giúp cân bằng lợi ích của Websockets.

Ví dụ: tải lên dựa trên Websocket có thể cung cấp khả năng tiếp tục tải lên lớn sau khi kết nối bị hủy và thiết lập lại (hãy nhớ rằng phim 5GB bạn muốn tải lên?).

Bằng cách mã hóa logic phân mảnh tải lên, thật dễ dàng để tiếp tục tải lên bị gián đoạn (phần khó là mã hóa thứ đó).

Điều gì về HTTP / 2 đẩy?

Tôi có lẽ nên thêm rằng tính năng đẩy HTTP / 2 không (và có lẽ không thể) thay thế Websockets.

Điều này đã được thảo luận ở đây trước đây , nhưng đủ để đề cập rằng một kết nối HTTP / 2 duy nhất phục vụ toàn bộ trình duyệt (tất cả các tab / cửa sổ), do đó, dữ liệu được đẩy bởi HTTP / 2 không biết nó thuộc về tab / cửa sổ nào, loại bỏ khả năng thay thế khả năng của Websocket để đẩy dữ liệu trực tiếp đến một tab / cửa sổ trình duyệt cụ thể.

Mặc dù Websockets rất tốt cho giao tiếp dữ liệu hai chiều nhỏ, AJAX vẫn mang một số lợi thế - đặc biệt là khi xem xét tải trọng lớn hơn (tải lên, v.v.).

Và an ninh?

Chà, nói chung, sự tin tưởng và kiểm soát được cung cấp cho một lập trình viên càng nhiều, công cụ càng mạnh mẽ ... và càng có nhiều mối lo ngại về bảo mật.

Bản chất AJAX sẽ chiếm ưu thế, vì tính bảo mật của nó được tích hợp vào mã của trình duyệt (đôi khi có thể nghi ngờ, nhưng nó vẫn còn đó).

Mặt khác, các cuộc gọi AJAX dễ bị tấn công "man in the middle" hơn, trong khi các vấn đề bảo mật của Websockets thường là các lỗi trong mã ứng dụng đưa ra lỗ hổng bảo mật (thường là logic xác thực phụ trợ là nơi bạn sẽ tìm thấy chúng).

Cá nhân tôi không thấy điều này là một sự khác biệt lớn, nếu bất cứ điều gì tôi nghĩ Websockets tốt hơn một chút, đặc biệt là khi bạn biết bạn đang làm gì.

Ý kiến ​​khiêm tốn của tôi

IMHO, tôi sẽ sử dụng Websockets cho mọi thứ trừ các lệnh gọi API REST. Tải lên dữ liệu lớn Tôi sẽ phân đoạn và gửi qua Websockets khi có thể.

Bỏ phiếu, IMHO, nên được đặt ngoài vòng pháp luật, chi phí trong lưu lượng truy cập mạng là khủng khiếp và Websocket đẩy đủ dễ dàng để quản lý ngay cả đối với các nhà phát triển mới.


2
Lỗi ngữ pháp nhỏ 'nếu có bất cứ điều gì tôi nghĩ ...' nghĩ
phát hiện ra

2
@spiatedmahn - Cảm ơn! Tôi đoán đó là những gì xảy ra Tôi sử dụng trình soạn thảo mã của mình để soạn thảo văn bản
Myst

1
Xin lỗi, tôi đã vắng mặt khi tiền thưởng hết hạn. Kế hoạch kém về phía tôi. Tôi đã đặt một tiền thưởng khác mà tôi sẽ trao cho bạn sau khi hết 23 giờ.
Duncan Jones

@Myst cảm ơn vì lời giải thích tuyệt vời này. Bạn thích điều gì cho các thông báo trực tiếp như fb / stackoverflow? Tôi đang thiết kế một dịch vụ web RestFull cho ứng dụng web của mình, nhưng rất bối rối tôi nên sử dụng tính năng thông báo nào? AJAX hoặc WebSockets?
TheCoder

Thông báo @puspen là (IMHO) rất phù hợp cho Websockets. Có rất nhiều quyết định được đưa ra khi bạn thiết kế logic kết nối lại và hàng đợi thông báo ngoại tuyến, nhưng thông báo thực tế vừa dễ viết mã vừa thực hiện với websockets.
Bí ẩn

18

Ngoài các vấn đề với các trình duyệt cũ hơn (bao gồm IE9, vì WebSockets sẽ được hỗ trợ bắt đầu từ IE10), vẫn còn những vấn đề lớn với các trung gian mạng chưa hỗ trợ WebSockets, bao gồm proxy trong suốt, proxy ngược và bộ cân bằng tải. Có một số nhà mạng di động chặn hoàn toàn lưu lượng truy cập WebSocket (nghĩa là, sau lệnh HTTP UPGRADE).

Sau nhiều năm trôi qua, WebSockets sẽ ngày càng được hỗ trợ nhiều hơn, nhưng trong thời gian này, bạn nên luôn có phương thức dự phòng dựa trên HTTP để gửi dữ liệu tới trình duyệt.


May mắn thay, hầu hết các khung WebSocket đều hỗ trợ các dự phòng, kể cả sử dụng Flash cho ổ cắm. Socketn.IO và SignalR đều là các khung công tác tốt ... mặc dù bạn thực sự bị hạn chế, như bạn đã đề cập vì proxy và bộ cân bằng tải. May mắn thay, cả Node.JS và IIS tiếp theo cũng làm rất tốt vai trò này.
Tracker1

Tò mò: nhà mạng nào chặn WebSocket trên cổng 80? Khối nào bảo mật WebSocket (WSS) trên cổng 443? Cái sau ngụ ý các proxy web MITM minh bạch bắt buộc .. không bao giờ thấy điều đó trong các mạng công cộng (chỉ các mạng công ty), vì nó yêu cầu cài đặt các CA CA mới vào trình duyệt.
oberstet

Ví dụ về Foe, hiện tại, Vodafone Italy chặn WS trên cổng 80, nhưng cho phép WSS trên cổng 443. Bạn có thể kiểm tra bất kỳ nhà cung cấp nào khá dễ dàng thông qua trang chủ của chúng tôi, nơi bạn có thể truy cập trong cả HTTP và HTTPS. Nó thử WebSockets và quay lại HTTP nếu chúng bị chặn. Sử dụng URL này để hiển thị một tiện ích ở giữa báo cáo giao thông hiện tại: lightstreamer.com/?s
Alessandro Alinone

17

Hầu hết các khiếu nại tôi đã đọc về websockets và bảo mật là từ các nhà cung cấp bảo mật của các công cụ bảo mật trình duyệt và bảo mật trình duyệt web. Vấn đề là họ không biết cách phân tích bảo mật lưu lượng websockets, bởi vì một khi nó đã thực hiện nâng cấp từ HTTP lên giao thức nhị phân websocket, nội dung gói và ý nghĩa của nó là cụ thể cho ứng dụng (dựa trên bất cứ điều gì bạn lập trình). Đây rõ ràng là một cơn ác mộng logistic đối với các công ty có sinh kế dựa trên việc phân tích và phân loại tất cả lưu lượng truy cập internet của bạn. :)


11

WebSockets không hoạt động trong các trình duyệt web cũ hơn và những trình duyệt hỗ trợ nó thường có các cách triển khai khác nhau. Đó là lý do chính đáng duy nhất tại sao họ không sử dụng tất cả thời gian thay cho AJAX.


8
Một lý do tốt hơn là yêu cầu AJAX là một yêu cầu HTTP bình thường, có nghĩa là nó có thể truy xuất tài nguyên HTTP; WebSockets không thể làm điều đó.
Dan D.

@Dan Điều gì xảy ra nếu các tệp hình ảnh ví dụ được gửi dưới dạng base64, CSS dưới dạng văn bản, JavaScript cũng dưới dạng văn bản và sau đó được thêm vào tài liệu? Điều đó có hợp lý không?
Jack

@DanD. +1, tôi đồng ý, tôi đoán rằng tôi đã tiếp cận câu hỏi nhiều hơn từ bối cảnh truyền dữ liệu nhanh chóng như trong ví dụ của câu hỏi, nhưng điều này hoàn toàn chính xác.
jli

@Dan D - đôi khi bạn không muốn tất cả những thứ nhảm nhí đó đi qua dòng, chẳng hạn như cookie và tiêu đề ...
vsync

8
@DanD., HTTP và WebSocket là hai giao thức riêng biệt, Tất nhiên chúng tôi không thể yêu cầu tài nguyên HTTP bằng giao thức WebSocket vì cùng lý do chúng tôi không thể yêu cầu tài nguyên WebSocket bằng giao thức HTTP! Điều đó không có nghĩa là khách hàng không thể yêu cầu các tệp html và / hoặc hình ảnh được gửi qua giao thức Websocket.
Pacerier

2

Tôi không nghĩ rằng chúng ta có thể so sánh rõ ràng về Websockets và HTTP vì chúng không phải là đối thủ cũng không giải quyết được các vấn đề tương tự.

Websockets là một lựa chọn tuyệt vời để xử lý truyền dữ liệu hai chiều trong thời gian gần theo thời gian thực, trong khi REST rất tốt cho việc liên lạc thường xuyên. Sử dụng websockets là một khoản đầu tư đáng kể, do đó nó là quá mức cần thiết cho các kết nối không thường xuyên.

Bạn có thể thấy rằng Websockets hoạt động tốt hơn khi có tải cao, HTTP nhanh hơn một chút trong một số trường hợp vì nó có thể sử dụng bộ nhớ đệm. So sánh REST với Websockets giống như so sánh táo với cam.

Chúng ta nên kiểm tra xem cái nào cung cấp giải pháp tốt hơn cho ứng dụng của chúng ta, cái nào phù hợp nhất trong trường hợp sử dụng của chúng ta sẽ thắng.


1
câu hỏi là về AJAX nói chung, không phải REST nói riêng. Đúng là AJAX có thể được sử dụng cho REST, nhưng nó cũng được sử dụng để bỏ phiếu và bỏ phiếu dài. Mặc dù tôi đồng ý với kết luận của bạn (như bạn có thể nói từ câu trả lời của tôi), tôi nghĩ rằng câu trả lời của bạn có thể phản ánh sự khác biệt (lưu ý rằng Websockets cũng có thể được sử dụng cho REST, mặc dù không sử dụng phương thức HTTP).
Bí ẩn

@Myst Tôi đồng ý với bạn.
Gaurav Gandhi

1

Một ví dụ về sự khác biệt giữa HTTP và Websockets ở dạng lib kích thước máy khách có thể xử lý điểm cuối Websocket như API REST và điểm cuối RESTful như Websockets trên máy khách. https://github.com/mikedeshazer/sockrest Ngoài ra, đối với những người đang cố gắng sử dụng API websocket trên máy khách hoặc ngược lại theo cách họ đã quen. Các libs / sockrest.js khá nhiều cho thấy rõ sự khác biệt (hay đúng hơn là được cho là).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.