AJAX-前後端互動的藝術
為什麼要用AJAX?
當我們通過提交表單向伺服器提交內容,或者進行一些其他操作,均涉及到了與瀏覽器之間的互動,傳統的方式與AJAX方式的處理方法是不同的
-
傳統方式:使用者觸發一個HTTP請求到 Web伺服器,伺服器接收並處理傳來的資料,然後回送一個新的頁面
- 分析1:這種方式浪費了很多資源和頻寬,很多情況下,返回的頁面大部分HTML程式碼是一致的
- 分析2:客戶在伺服器處理請求期間,只能等待,不能進行操作
-
AJAX方式:AJAX可以只向伺服器傳送請求,並且取回必要的資料,客戶端採用 JavaScript 的方式處理來自伺服器的回應
- 分析1:大大的減少了資料量,伺服器回應速度更快,部分處理轉移到了客戶端,減輕了伺服器的負荷
- 分析2:可以實現客戶端和伺服器的非同步通訊方式(後面說)
舉個例子:
-
如果我們通過 “傳統方式” 對這個頁面中的內容分頁,這樣的話,每次分頁都會重新整理整個頁面,導致已經成功顯示的頭部資訊,以及左側固定資訊,重新從伺服器中獲取,造成了頻寬和伺服器資源的孫歡,同時使用者也增加了等待時間,
-
如果我們通過 “AJAX方式” 實現內容分頁,AJAX只需要從伺服器中獲取到 需要的這些資訊也就是圖中的紅色區域內的資料,這樣就不需要重新整理整個頁面,只需要區域性重新整理就可以了,既能節省資源,又提升了使用者的體驗感
什麼是 AJAX
AJAX(Asynchronous JavaScript and XML) 非同步的 JavaScript 和 XML,是指一種建立互動式網頁應用的網頁開發技術
- 第一種讀法:AJAX —— ['eidʒæks] 標準音標讀法
- 第二種讀法:阿賈克斯
(內容選自:what is Ajax 中文為是自己翻譯的,功底過淺,或許不是很理想)
Ajax uses XHTML for content, CSS for presentation, along with Document Object Model and JavaScript for dynamic content display.
AJAX 使用 XHTML 來描述內容,CSS設定樣式,DOM 和 JavaScript實現動態展示內容。
Conventional web applications transmit information to and from the sever using synchronous requests. It means you fill out a form, hit submit, and get directed to a new page with new information from the server.
傳統的 web應用程式使用同步的方式向伺服器傳送和傳輸資料,這就是說,你填完一個表單後,點選提交,然後會重定向到一個含新資料的頁面(資料由伺服器傳來)。
With AJAX, when you hit submit, JavaScript will make a request to the server, interpret the results, and update the current screen. In the purest sense, the user would never know that anything was even transmitted to the server.
使用AJAX的時候,當你點選 “提交”,JavaScript 會傳送一個請求到伺服器,解析請求響應,並且更新到頁面中,純粹來說,使用者是無法感覺到任何資料被傳送到了伺服器。
XML is commonly used as the format for receiving server data, although any format, including plain text, can be used.
XML一般作為從服務端接受資料的格式,當然也可以用包括 plain text 等 其他格式。
AJAX is a web browser technology independent of web server software.
AJAX 是一種與 web 服務軟體向獨立的 web 瀏覽器技術。
A user can continue to use the application while the client program requests information from the server in the background.
當客戶端在向服務端請求資料的時候,使用者仍然可以繼續使用應用。
Intuitive and natural user interaction. Clicking is not required, mouse movement is a sufficient event trigger.
(AJAX展現出一種)直觀自然的使用者互動體驗,點選事件不再是必須的,滑鼠移動事件已經足夠。
Data-driven as opposed to page-driven.
(AJAX)使用資料驅動而不是頁面驅動。
看完了這些說明,我們解釋一下定義中的兩個重點概念:
(一) 什麼是非同步呢?
(1) 非同步的基本概念
非同步和同步往往是同時被提到的兩個概念,這兩者都是基於客戶端和伺服器端相互通訊的基礎上
- 同步:客戶端必須的等待伺服器端給予的響應,在此期間不能進行其他操作
- 非同步:與同步不同,客戶端不需要等待伺服器響應,在此期間可以進行任何操作
簡單概述流程:
同步:傳送請求 → 等待伺服器處理 → 返回
非同步:事件觸發 → 伺服器處理 (不等待)→ 處理結束
(2) 非同步的好處
AJAX 就是一種可以在無需重新載入整個網頁的情況下 就可以實現與客戶端與伺服器的非同步通訊
往簡單了說就是:不用重新整理整個網頁,就能修改網頁區域性內容
正如我們開頭所說到的,在開發中,如果每一次區域性的小修改都進行頁面重新整理,這顯然對效能會有所降低,而且使用者正在執行的操作也會中斷
(二) 資料傳輸格式
Aajx 的英文全稱為 Asynchronous JavaScript and XML ,雖然包含了XML,但是資料格式還可以有 JSON等
關於其資料傳輸格式有這樣一種說明:
XML is commonly used as the format for receiving server data, although any format, including plain text, can be used.
XML一般作為從服務端接受資料的格式,當然也可以用包括 plain text 等 其他格式
AJAX中常使用的兩種資料傳輸格式為:XML/JSON ,不過現在更多的是使用 JSON 格式,它作為一種輕量級的資料交換格式,更小,更快,也更加容易解析
如果對於XML/JSON 還不夠熟悉的話,可以先去了解一些基本的概念以及用法(不過對於本篇基本無影響)
AJAX的優缺點及應用場景
(一) 優缺點
-
優點:
- 區域性重新整理,優化了使用者體驗
- 非同步通訊,不需要打斷使用者操作,具有良好的響應能力
- 將一些工作從伺服器轉移到客戶端中,節省了伺服器和頻寬資源
- 按需取資料 ,減輕了伺服器負擔,也大大減少了冗餘請求
-
缺點:
- AJAX 主要依賴於JavaScript ,瀏覽器對 JavaScript 的相容性將直接影響 AJAX的使用
- 瀏覽器的後退機制被破壞,這也正是區域性重新整理所帶來的問題,不過現在有一些方式可以儘可能彌補這些問題
- 移動端對 AJAX 的支援沒有那麼好
(二) 應用場景
- ① 搜尋框聯想列表
- ② 區域性重新整理分頁效果
- ③ 同頁面載入更多資料
- ④ 表單資料校驗
XMLHttpRequest - 核心物件
XMLHttpRequest = AJAX?
作為一個小菜鳥而言,僅限於一下不算太深入的應用,我常常會有這樣一種感覺,XMLHttpRequest = AJAX 嗎?
(內容選自:what is Ajax 中文為是自己翻譯的,功底過淺,或許不是很理想)
可按個人需要選擇是否跳過這個問題,直接跳轉到後面的語法等部分
AJAX stands for Asynchronous JavaScript and XML. AJAX is a new technique for creating better, faster, and more interactive web applications with the help of XML, HTML, CSS, and JavaScript.
AJAX 所代表的的是 JavaScript和XML。AJAX是一種新技術,它通過利用 XML,HTML,CSS 和 JavaScript 來建立更好,更快,更具有互動性的Web應用程式。
AJAX is based on the following open standards −
AJAX 是基於以下公共的標準
Browser-based presentation using HTML and Cascading Style Sheets (CSS).
瀏覽器使用 HTML 以及 CSS 進行展示。
Data is stored in XML format and fetched from the server.
從服務端獲取的資料以 XML 格式儲存。
Behind-the-scenes data fetches using XMLHttpRequest objects in the browser.
在後臺使用 XMLHttpRequest 請求資料 。
JavaScript to make everything happen.
JavaScript 負責整個流程的實現
看完了上面的說明, 我們可以看出來,AJAX不是指一種單一的技術,而是,利用了多種技術而產生的一種技術方案,上面提到的,主要依賴的技術也就是 HTML CSS JavaScript,而真正負責我們實現瀏覽器與伺服器 進行請求與相應的就是 XMLHttpRequest
下面,我們來重點了解一下它
(一) XMLHttpRequest 基本原理
Ajax中最大的特點 就是請求會被非同步物件XMLHttpRequest進行封裝,然後再傳送到伺服器,接著伺服器以流的形式將資料返回給瀏覽器
也正是因為伺服器返回的資料是通過流的形式傳送的**,XMLHttpRequest物件會不停的監聽伺服器**,且得到伺服器資料,所以瀏覽器不需要重新整理就可以獲取伺服器端的資料
(二) XMLHttpRequest 方法和屬性
注:下面會講解具體的用法,在此處僅作為方法和屬性的基本歸納和梳理,不做過於具體的說明,可先簡單瀏覽,待到看完文章再回來閱讀
方法:
-
open( )
準備初始化一個AJAX請求
-
open( method, URL )
-
open( method, URL, async )
-
open( method, URL, async, userName )
-
open( method, URL, async, userName, password )
-
-
send( content )
傳送請求
-
setRequestHeader( label, value )
設定請求頭資訊
-
getAllResponseHeaders()
以字串的形式返回完整的HTTP頭資訊集
-
getResponseHeader( headerName )
返回指定的響應頭部資訊
-
abort()
取消當前的請求
屬性:
-
onreadystatechange
監聽事件,當 readyState 屬性發生變化時觸發
-
readyState
定義了 XMLHttpRequest 物件的當前狀態 (0 1 2 3 4)
-
responseText
以字串的形式返回響應
-
responseXML
返回XML格式的響應,此屬性返回一個XML文件物件
-
status
返回 HTTP 狀態 (e.g., 404 for "Not Found" and 200 for "OK").
-
statusText
返回 HTTP 狀態的說明 (e.g., "Not Found" or "OK").
附:思維導圖
使用 AJAX 的步驟
(一) 建立 XMLHttpRequest 物件
針對不同版本的瀏覽器,建立 XMLHttpRequest 物件有著不同的方法,分為兩類:
- 比較新的現代瀏覽器:IE7+, Firefox, Chrome, Opera, Safari
- 舊版本的IE瀏覽器等:IE6, IE5
針對不同的情況我們可以需要一個可以相容各種瀏覽器的通用函式
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var ajaxRequest;
try {
// 相容 IE7+, Firefox, Chrome, Opera, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// 相容 Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return false;
}
}
}
}
</script>
複製程式碼
簡單的也可以這麼寫
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var xhr;
if (window.XMLHttpRequest) {
xhr=new XMLHttpRequest();
}
else {
xhr=new ActiveXObject("Microsoft.XMLHTTP");
}
}
</script>
複製程式碼
(二) 準備AJAX請求
xhr.open(method, URL, async);
複製程式碼
- 引數1:請求方式(Get、Post)
- get:請求引數在URL後拼,send方法為空
- post:請求引數在send方法中寫,open方法中僅僅寫 URL即可
- 引數2:請求URL
- 引數3:true-非同步,false-同步(一般均為 true)
(1) 必須知道的 GET 與 POST
GET 請求:
GET 請求常用於獲取伺服器的資料,例如我們使用 連結(href)或 URL 等發起請求,而我們常常需要將頁面中的引數,傳遞到後端進行定位或處理,GET請求的方式就會將資料拼接到 RUL後面,方便伺服器進行解析
格式:?
、開頭,&
分隔字串,引數之間不需要空格,引數值不需要單雙引號包括,例如:
loginServlet?username=admin&password=admin
複製程式碼
POST 請求:
POST 請求用於向伺服器傳送被處理的資料,提交表單既可以使用GET,也可以使用POST方式,推薦使用POST方式,查詢資料的時候推薦使用GET方式
GET:沒有請求體,但空行是存在的,附帶的引數有限制,資料容量不能超過1k
POST:存在請求體,可以在請求的實體內容中向伺服器傳送資料,傳送的資料量是無限制的
(2) GET 方式請求的格式:
xhr.open("GET","loginServlet?username=admin&password=admin",true);
複製程式碼
(3) POST 方式請求的格式:
xhr.open("POST",loginServlet,true);
複製程式碼
使用 POST 方式提交的時候,其需要傳送的資料怎麼辦呢? 答案是:在 send 的方法中作為引數進行傳遞,發往伺服器
(三) AJAX 傳送請求
xhr.send();
複製程式碼
(1) GET 方式請求的格式:
xhr.send(null);
複製程式碼
使用 GET 方式還是比較簡單的,只需要在send方法彙總傳入一個null值即可了
(2) POST 方式請求的格式:
如果需要像 HTML 表單那樣 POST 資料,請使用 setRequestHeader() 來新增 HTTP 頭。然後在 send() 方法中規定您希望傳送的資料:
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("username=admin&password=admin");
複製程式碼
(四) 處理響應
xhr.onreadystatechange=function() {
//判斷readyState就緒狀態是否為4,判斷status響應狀態碼是否為200
if (xhr.readyState==4 && xhr.status==200) {
//獲取伺服器的響應結果
var responseText = xhr.responseText;
alert(responseText);
}
}
複製程式碼
狀態 | 描述 |
---|---|
readyState = 0 | 請求未初始化:在建立XMLHttpRequest物件之後,但在呼叫open()方法之前 |
readyState = 1 | 請求已建立:在呼叫open()方法之後但在呼叫send()之前 |
readyState = 2 | 請求已傳送:呼叫send()之後 |
readyState = 3 | 求正在處理中:瀏覽器與伺服器建立通訊之後,但伺服器未完成響應之前 |
readyState = 4 | 求已完成:請求完成後,並且已從伺服器完全接收到響應資料 |
狀態碼 | 解釋 |
---|---|
200 | 請求成功 |
302 | 請求重定向 |
304 | 請求資源沒有改變 |
404 | 請求資源補不存在,屬性客戶端錯誤 |
500 | 伺服器內部錯誤 |
編寫一個簡單的 AJAX 程式(原生方式)我們簡單的模擬一個表單校驗的程式
-
index.html
注:為效果更容易理解,設定按鈕點選事件進行校驗,實際可使用失/獲焦點相關方法進行優化
<input type="text" id="username">
<input type="button" onclick="ajaxFunction()" value="向後臺判斷使用者名稱是否存在"></br>
<div id="msgError">校驗顯示區域</div>
複製程式碼
- JavaScript 程式碼
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var ajaxRequest;
try {
// 相容 IE7+, Firefox, Chrome, Opera, Safari
ajaxRequest = new XMLHttpRequest();
} catch (e) {
// 相容 Internet Explorer Browsers
try {
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return false;
}
}
}
//準備請求
ajaxRequest.open("POST", "loginServlet", true);
//由於是POST提交方式,所以新增 HTTP 頭
ajaxRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//獲取到表單中輸入的值
var name_input = document.getElementById("username").value;
//傳送請求
ajaxRequest.send("username=" + name_input);
ajaxRequest.onreadystatechange = function () {
//判斷readyState就緒狀態是否為4,判斷status響應狀態碼是否為200
if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200) {
//獲取伺服器的響應結果
var responseText = ajaxRequest.responseText;
var div = document.getElementById("msgError");
div.innerText = responseText;
}
}
}
</script>
複製程式碼
- loginServlet
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
//此語句僅為方便判斷是否後端正常收到了前端的資料,可選擇刪除
System.out.println("接收到的資料:" + username);
try {
if (username.equals("admin")) {
Thread.sleep(5000);
response.getWriter().print("該使用者名稱已經存在");
} else {
Thread.sleep(5000);
response.getWriter().print("該使用者名稱可以註冊");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
複製程式碼
我們這樣就在無需重新載入整個網頁的情況下 就可以實現與客戶端與伺服器的非同步通訊,我們為了演示,同時在後臺主動設定 延時5秒響應的情況下,但我們使用者仍然可以在此期間進行操作,具體情況,可以自行簡單模擬試驗
JQuery 實現方式
使用原生的 JavaScript 實現 AJAX 確實比較麻煩,而 使用 Jquery 也可以幫助我們實現這樣一種需求,而且也會讓我們的程式碼更加簡潔,直觀
舉個例子:
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var name_input = document.getElementById("username").value;
$.ajax({
url: "loginServlet",
type: "POST",
data: {"username": name_input},
success: function (data) {
var div = document.getElementById("msgError");
div.innerText = data;
},
error: function () {
alert("發生錯誤");
}
});
}
</script>
複製程式碼
- url:請求路徑
- type:請求方式
- date:請求引數,想對應於原生JS實現的,data: "username=admin&age=20"
- success:響應成功後的回撥函式
- error:果請求響應出現錯誤,會執行的回撥函式
- dateType:設定接受到的響應資料的格式(上例中未寫)
當然它的引數和設定選項不止這些,在這裡只選擇了一些相對簡單或者說必須的,詳情可以參考 JQuery API 文件
舉個例子:
在 Servlet 和 html 均不變的基礎上,我們修改 js程式碼,使用jquery的方式來實現同樣的功能
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var name_input = document.getElementById("username").value;
$.ajax({
url: "loginServlet",
type: "POST",
data: {"username": name_input},
success: function (data) {
var div = document.getElementById("msgError");
div.innerText = data;
},
error: function () {
alert("發生錯誤");
}
});
}
</script>
複製程式碼
經過測試結果是一樣的
JQuery確實極大的簡化了我們的程式碼,但是如果你只是想快速的實現這一種需求,JQuery 其實還提供了兩個更為簡單的方式,以取代複雜 $.ajax
(一) $.get()方法
說明:這是一個簡單的 GET 請求功能,來取代複雜的 $.ajax
完整結構: $.get(url,[data],callback,type)
-
url:待載入頁面的URL地址
-
data:待傳送 Key/value 引數
-
callback:載入成功時回撥函式
-
type:返回內容格式,xml, html, script, json, text, _default
這種方式旨在快速的實現請求,當請求成功的時候可以呼叫回撥函式,如果需要在出錯的時候執行函式,還是需要使用 $.ajax()
(二) $.post()方法
說明:這是一個簡單的 POST 請求功能,來取代複雜的 $.ajax
完整結構: $.post(url, [data], [callback], [type])
-
url:傳送請求地址
-
data:待傳送 Key/value 引數
-
callback:傳送成功時回撥函式
-
type:返回內容格式,xml, html, script, json, text, _default。
還是沿用上面的 html和Servlet,修改function程式碼
<script language="javascript" type="text/javascript">
function ajaxFunction() {
var name_input = document.getElementById("username").value;
$.get("loginServlet",{username:name_input},function (data) {
var div = document.getElementById("msgError");
div.innerText = data;
},"text");
}
</script>
複製程式碼
總結:$.get()
方法 和 $.post()
方法方法均可以快速簡潔的完成一些基本操作,如果操作比較複雜,還是需要使用 $.ajax()
方式
總結:
AJAX 的的基本知識,以及使用 JavaScript 和 JQuery 這兩種實現方式,我們就已經介紹完了,到現在為止,如何發起並且接收響應已經不在話下了,並且我們對 AJAX 有了一定的認識,但是 AJAX 的一些應用場景,以及AJAX 如何搭配 常見的 如 JSON 等資料格式,實現前後端的互動,並沒有提到,我們就放到後面說,將全部的內容擠到一起,無論是從篇幅或者說內容的針對性都是不夠強的,不過AJAX 也確實是我們成長路上不可不學的一門技術了,有什麼不清楚的, 可以嘗試著看一些國內外的資源站點,w3chool、tutorialspoint 等等,多翻翻 API 文件,尤其是一些英文的文件和資料,我感覺對我個人幫助還是很大的。
同樣在此感謝大家的支援!謝謝!
大家的每一個閱讀和讚我都當做了喜歡!❤️
結尾:
如果文章中有什麼不足,或者錯誤的地方,歡迎大家留言分享想法,感謝朋友們的支援!
如果能幫到的話,那就來關注我吧!如果你更喜歡微信文章的閱讀方式,也可以關注我的公眾號哈
在這裡的我們素不相識,卻都在為了自己的夢而努力 ❤
一個堅持推送原創開發技術文章的公眾號:理想二旬不止