首頁 web前端 js教程 反向Ajax 30分鐘快速掌握

反向Ajax 30分鐘快速掌握

May 23, 2018 pm 03:49 PM
ajax 快速 掌握

這篇文章主要介紹了反向Ajax 30分鐘快速掌握的相關資料,需要的朋友可以參考下

場景1:當有新郵件的時候,網頁自動彈出提示信息而無需用戶手動的刷新收件匣。

場景2:當使用者的手機掃描完成頁面中的二維碼以後,頁面會自動跳轉。

場景3:在類似聊天室的環境中有任何人發言,所有登入使用者都可以即時看見訊息。

與傳統的MVC模型請求必須從客戶端發起由伺服器回應相比,使用反向Ajax能夠模擬伺服器端主動向客戶端推送事件從而提高使用者體驗。本文將分成兩個部分討論反向Ajax技術,包括:Comet和WebSocket。文章旨在示範如何實現以上兩種技術手段,Struts2或SpringMVC中的應用並未涉及。此外,Servlet的配置也採用註解的方式,相關知識大家可以參考其它資料。

一、Comet(最佳的相容手段)

Comet本質上則是這樣的概念:能夠從伺服器端向客戶端發送資料。在一個標準的 HTTP Ajax 請求中,資料是發送給伺服器端的,反向 Ajax 以某些特定的方式來模擬發出一個 Ajax 請求,這樣的話,伺服器就可以盡可能快地向客戶端發送事件。由於普通HTTP請求往往會伴隨頁面的跳轉,而推播事件則需要瀏覽器停留在同一個頁面或框架下,因此Comet的實作只能夠透過Ajax來完成。

它的實作過程如下:頁面載入的時候隨即向伺服器發送一條Ajax請求,伺服器端取得請求並將它保存在一個執行緒安全的容器中(通常為隊列)。同時伺服器端仍然可以正常回應其他請求。當需要推送的事件到來的時候,伺服器遍歷容器中的請求在傳回應答後刪除。於是所有停留在頁面中的瀏覽器都會獲得該應答,並再次發送Ajax請求,重複上述過程。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!DOCTYPE html>
<html lang="en">
<base href="<%=basePath%>">
<head>
<title>WebSocket</title>
<script type="text/javascript" src="static/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function() {
connect();
$("#btn").click(function() {
var value = $("#message").val();
$.ajax({
url : "longpolling?method=onMessage&msg=" + value,
cache : false,
dataType : "text",
success : function(data) {
}
});
});
});
function connect() {
$.ajax({
url : "longpolling?method=onOpen",
cache : false,
dataType : "text",
success : function(data) {
connect();
alert(data);
}
});
}
</script>
</head>
<body>
<h1>LongPolling</h1>
<input type="text" id="message" />
<input type="button" id="btn" value="发送" />
</body>
</html>
登入後複製

我們注意到,由btn發送的請求其實並不需要取得回應。整個過程的關鍵是需要客戶端始終讓伺服器保持connect()的請求。而伺服器端首先需要支援這種非同步的回應方式,幸運的是目前為止絕大部分的Servlet容器都已經提供了良好的支援。以下以Tomcat為例:

package servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(value="/longpolling", asyncSupported=true)
public class Comet extends HttpServlet {
private static final Queue<AsyncContext> CONNECTIONS = new ConcurrentLinkedQueue<AsyncContext>();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("onOpen")) {
onOpen(req, resp);
} else if (method.equals("onMessage")) {
onMessage(req, resp);
}
}
private void onOpen(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
AsyncContext context = req.startAsync();
context.setTimeout(0);
CONNECTIONS.offer(context);
}
private void onMessage(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = req.getParameter("msg");
broadcast(msg);
}
private synchronized void broadcast(String msg) {
for (AsyncContext context : CONNECTIONS) {
HttpServletResponse response = (HttpServletResponse) context.getResponse();
try {
PrintWriter out = response.getWriter();
out.print(msg);
out.flush();
out.close();
context.complete();
CONNECTIONS.remove(context);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
登入後複製

ConcurrentLinkedQueue是Qu​​eue佇列的一個線程安全實現,這裡使用它來作為保存請求的容器。 AsyncContext是Tomcat支援的非同步環境,不同的伺服器使用的物件也略有不同。 Jetty支援的物件是Continuation。完成了廣播的請求需要透過context.complete()將相關請求結束,並使用CONNECTIONS.remove(context)刪除佇列。

二、WebSocket(來自HTML5的支援)

使用HTTP 長輪詢的Comet 是可靠地實現反向Ajax 的最佳方式,因為現在所有瀏覽器都提供了這方面的支援。

WebSockets 在 HTML5 中出現,是比 Comet 更新的反向 Ajax 技術。 WebSockets 支援雙向、全雙工通訊頻道,許多瀏覽器(Firefox、Google Chrome 和 Safari)也支援它。連線透過 HTTP 請求(也稱為 WebSockets 握手)和一些特殊的標頭 (header)。連線一直處於啟動狀態,您可以用 JavaScript 編寫和接收數據,就像您使用原始 TCP 套接字一樣。

透過輸入 ws:// 或 wss://(在 SSL 上)啟動 WebSocket URL。如圖:

首先:WebSockets並非在所有瀏覽器上都能獲得良好的支持,顯然IE又拖了後腿。因此當你打算使用這項技術之前必須考慮到用戶的使用環境,如果你的專案面向的是互聯網或包括手機端用戶,奉勸大家三思。

其次:WebSockets提供的請求區別於普通的HTTP請求,它是一種全雙工通訊且始終處於啟動狀態(如果你不去關閉它的話)。這意味著你不用每次獲得應答後再次向伺服器發送請求,這樣可以節省大量的資源。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ path + "/";
String ws = "ws://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html>
<html lang="en">
<base href="<%=basePath%>">
<head>
<title>WebSocket</title>
<script type="text/javascript" src="static/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function() {
var websocket = null;
if ("WebSocket" in window){
websocket = new WebSocket("<%=ws%>websocket");
} else {
alert("not support");
}
websocket.onopen = function(evt) {
}
websocket.onmessage = function(evt) {
alert(evt.data);
}
websocket.onclose = function(evt) {
}
$("#btn").click(function() {
var text = $("#message").val();
websocket.send(text);
});
});
</script>
</head>
<body>
<h1>WebSocket</h1>
<input type="text" id="message" />
<input type="button" id="btn" value="发送"/>
</body>
</html>
登入後複製

JQuery對WebSocket還未提供更良好的支持,因此我們必須使用Javascript來編寫部分程式碼(好在並不複雜)。並且打部分常見的伺服器都可以支援ws請求,以Tomcat為例。在6.0版本中WebSocketServlet物件已經被標註為@java.lang.Deprecated,7.0以後的版本支援jsr365提供的實現,因此你必須使用註解來完成相關配置。

package servlet;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint("/websocket")
public class WebSocket {
private static final Queue<WebSocket> CONNECTIONS = new ConcurrentLinkedQueue<WebSocket>();
private Session session;
@OnOpen
public void onOpen(Session session) {
this.session = session;
CONNECTIONS.offer(this);
}
@OnMessage
public void onMessage(String message) {
broadcast(message);
}
@OnClose
public void onClose() {
CONNECTIONS.remove(this);
}
private synchronized void broadcast(String msg) {
for (WebSocket point : CONNECTIONS) {
try {
point.session.getBasicRemote().sendText(msg);
} catch (IOException e) {
CONNECTIONS.remove(point);
try {
point.session.close();
} catch (IOException e1) {
}
}
}
}
}
登入後複製

三、總結(從請求到推送)

#

在傳統通訊方案中,如果系統 A 需要係統 B 中的信息,它會向系統 B 發送一個請求。系統 B 將處理請求,而係統 A 會等待回應。處理完成後,會將回應傳回系統 A。在同步 通訊模式下,資源使用效率比較低,這是因為等待回應時會浪費處理時間。

在非同步 模式下,系統 A 將訂閱它想從系統 B 中取得的資訊。然後,系統 A 可以向系統 B 發送通知,也可以立即傳回訊息,同時,系統 A 可以處理其他事務。這個步驟是可選的。在事件驅動應用程式中,通常不必要求其他系統發送事件,因為您不知道這些事件是什麼。在系統 B 發布回應之後,系統 A 會立即收到該回應。

Web 框架過去通常依賴傳統 “請求-回應” 模式,該模式會導致頁面重新整理。隨著 Ajax、Reverse Ajax 以及 WebSocket 的出現,現在可以將事件驅動架構的概念輕鬆應用於 Web,獲得去耦合、可擴展性和反應性 (reactivity) 等好處。更良好的使用者體驗也會帶來新的商業契機。

上面是我整理給大家的,希望今後對大家有幫助。

相關文章:

Ajax實現智慧提示搜尋功能

#Ajax請求成功後開啟新視窗位址

利用ajax實現非同步刷新請求

以上是反向Ajax 30分鐘快速掌握的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1323
25
PHP教程
1272
29
C# 教程
1251
24
PHP 與 Ajax:建立一個自動完成建議引擎 PHP 與 Ajax:建立一個自動完成建議引擎 Jun 02, 2024 pm 08:39 PM

使用PHP和Ajax建置自動完成建議引擎:伺服器端腳本:處理Ajax請求並傳回建議(autocomplete.php)。客戶端腳本:發送Ajax請求並顯示建議(autocomplete.js)。實戰案例:在HTML頁面中包含腳本並指定search-input元素識別碼。

解決jQuery AJAX請求遇到403錯誤的方法 解決jQuery AJAX請求遇到403錯誤的方法 Feb 20, 2024 am 10:07 AM

標題:解決jQueryAJAX請求出現403錯誤的方法及程式碼範例403錯誤是指伺服器禁止存取資源的請求,通常會導致出現這個錯誤的原因是請求缺少權限或被伺服器拒絕。在進行jQueryAJAX請求時,有時會遇到這種情況,本文將介紹如何解決這個問題,並提供程式碼範例。解決方法:檢查權限:首先要確保請求的URL位址是正確的,同時驗證是否有足夠的權限來存取該資

解決jQuery AJAX請求403錯誤的方法 解決jQuery AJAX請求403錯誤的方法 Feb 19, 2024 pm 05:55 PM

jQuery是一個受歡迎的JavaScript函式庫,用來簡化客戶端端的開發。而AJAX則是在不重新載入整個網頁的情況下,透過發送非同步請求和與伺服器互動的技術。然而在使用jQuery進行AJAX請求時,有時會遇到403錯誤。 403錯誤通常是伺服器禁止存取的錯誤,可能是由於安全性原則或權限問題導致的。在本文中,我們將討論如何解決jQueryAJAX請求遭遇403錯誤

如何解決jQuery AJAX報錯403的問題? 如何解決jQuery AJAX報錯403的問題? Feb 23, 2024 pm 04:27 PM

如何解決jQueryAJAX報錯403的問題?在開發網頁應用程式時,經常會使用jQuery來發送非同步請求。然而,有時在使用jQueryAJAX時可能會遇到錯誤代碼403,表示伺服器禁止存取。這種情況通常是由伺服器端的安全性設定所導致的,但可以透過一些方法來解決這個問題。本文將介紹如何解決jQueryAJAX報錯403的問題,並提供具體的程式碼範例。一、使

Win11系統中「我的電腦」路徑有何不同?快速找方法! Win11系統中「我的電腦」路徑有何不同?快速找方法! Mar 29, 2024 pm 12:33 PM

Win11系統中「我的電腦」路徑有何不同?快速找方法!隨著Windows系統的不斷更新,最新的Windows11系統也帶來了一些新的變化和功能。其中一個常見的問題是使用者在Win11系統中找不到「我的電腦」的路徑,這在先前的Windows系統中通常是很簡單的操作。本文將介紹Win11系統中「我的電腦」的路徑有何不同,以及快速尋找的方法。在Windows1

如何使用Ajax從PHP方法取得變數? 如何使用Ajax從PHP方法取得變數? Mar 09, 2024 pm 05:36 PM

使用Ajax從PHP方法取得變數是Web開發中常見的場景,透過Ajax可以實作頁面無需刷新即可動態取得資料。在本文中,將介紹如何使用Ajax從PHP方法中取得變量,並提供具體的程式碼範例。首先,我們需要寫一個PHP檔案來處理Ajax請求,並傳回所需的變數。下面是一個簡單的PHP檔案getData.php的範例程式碼:

WordPress 網站建立指南:快速建立個人網站 WordPress 網站建立指南:快速建立個人網站 Mar 04, 2024 pm 04:39 PM

WordPress網站建立指南:快速建立個人網站隨著數位時代的到來,擁有一個個人網站已經成為了一種時尚和必要。而WordPress作為最受歡迎的網站建立工具,讓建立個人網站變得更容易、更方便。本文將為大家提供一個快速建立個人網站的指南,包含具體的程式碼範例,希望可以幫助到想要擁有自己網站的朋友們。第一步:購買網域和主機在開始建立個人網站之前,首先要購買自己

PHP 與 Ajax:建立動態載入內容的解決方案 PHP 與 Ajax:建立動態載入內容的解決方案 Jun 06, 2024 pm 01:12 PM

Ajax(非同步JavaScript和XML)允許在不重新載入頁面情況下新增動態內容。使用PHP和Ajax,您可以動態載入產品清單:HTML建立一個帶有容器元素的頁面,Ajax請求載入資料後將資料加入到該元素中。 JavaScript使用Ajax透過XMLHttpRequest向伺服器傳送請求,從伺服器取得JSON格式的產品資料。 PHP使用MySQL從資料庫查詢產品數據,並將其編碼為JSON格式。 JavaScript解析JSON數據,並將其顯示在頁面容器中。點選按鈕觸發Ajax請求,載入產品清單。

See all articles