洛谷月賽
概述
AJAX,即Asynchronous JavaScript and XML(非同步的 JavaScript 和 XML)。Ajax通過在後臺與伺服器進行少量資料交換,可以使網頁實現非同步更新。這意味著可以在不重新載入整個網頁的情況下,對網頁的某部分進行更新。
為什麼使用Ajax?
在之前的開發,每當使用者向伺服器傳送請求,哪怕只是需要更新一點點的區域性內容,伺服器都會將整個頁面進行重新整理。其缺點是:
- 效能會有所降低
- 使用者的操作頁面會中斷(整個頁面被重新整理了)
XMLHttpRequest物件
使用Ajax進行客戶端與服務端的非同步通訊的一個關鍵物件就是XMLHttpRequest
工作原理(來自java3y-Ajax入門):
傳統的web前端與後端的互動中,瀏覽器直接訪問Tomcat的Servlet來獲取資料。Servlet通過轉發把資料傳送給瀏覽器。
當使用AJAX之後,瀏覽器是先把請求傳送到XMLHttpRequest非同步物件之中,非同步物件對請求進行封裝,然後再與傳送給伺服器。伺服器並不是以轉發的方式響應,而是以流的方式把資料返回給瀏覽器。
XMLHttpRequest非同步物件會不停監聽伺服器狀態的變化,得到伺服器返回的資料,就寫到瀏覽器上【因為不是轉發的方式,所以是無重新整理就能夠獲取伺服器端的資料】
XMLHttpRequest的建立
並不是所有的瀏覽器都支援XMLHttpRequest物件,如下:
var xmlhttp;
if (window.XMLHttpRequest)
{// IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{//IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
XMLHttpRequest物件的屬性
- onreadystatechange:請求狀態改變的事件觸發器,每當readyState的屬性改變時,就會呼叫該函式。 一般用於指定回撥函式
- readyState:存有的XMLHttpRequest的狀態從0到4發生變化。
- 0:請求未初始化 。此時XMLHttpRequest物件已被建立,但還沒有呼叫open方法。
- 1:請求已建立。呼叫了open方法,建立了http請求,但還沒有呼叫send方法,即還沒有傳送請求。
- 2:請求已傳送。請求已經被髮送,但還沒用到達伺服器。
- 3:請求處理中。請求已傳送到伺服器,伺服器正在處理請求並返回響應資料。
- 4:請求已完成,並已接收全部響應資料。
- reponseText:以文字形式返回響應。
- responseXML:以XML格式返回響應。可以使用JavaScript的DOM API操作返回的xml內容。
- status:將狀態返回為數字(例如,“Not Found”為404,“OK”為200)
- statusText:以字串形式返回狀態(例如,“Not Found”或“OK”)
XMLHttpRequest物件的方法
重要方法如下:標粗體的方法為常用方法。
-
void open(method,URL,async)
:根據請求形式和utl建立HTTP請求,async指定是否非同步,true為非同步,false為同步。 -
void open(method,URL,async,userName,password)
:userName和password是在http認證的時候會用到的。 -
setRequestHeader(label,value)
:設定請求體資訊。使用post方式傳送請求時,需設定如下請求頭:xmlHttpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
-
void send(content)
:傳送請求給伺服器。- 若是傳送post請求,要傳送的引數資訊需通過send方法傳送。
- 對於get請求,content可以不寫或為null。引數的傳送通過url即可。
-
abort():取消當前請求。
-
getAllResponseHeaders():以字串形式返回完整的HTTP標頭集。
-
getResponseHeader(headerName) :返回指定HTTP標頭的值。
簡單示例
該示例伺服器端使用servlet。
示例內容:點選按鈕,傳送Ajax請求,並把從伺服器獲取到的文字插入到當前頁面。
伺服器端的Servlet:
public class OneServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("OneServlet.doGet");
//客戶端使用了post方式的請求,引數資料將會被request物件解析,需要設定其字符集,避免亂碼
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
String age = req.getParameter("age");
System.out.println("從客戶端傳送來的資料:");
System.out.println("username = " + username);
System.out.println("age = " + age);
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("這是通過Ajax從伺服器端獲取的文字資料。。。");
}
}
OneServlet的web.xml配置:
<servlet>
<servlet-name>one</servlet-name>
<servlet-class>com.servlet.OneServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>one</servlet-name>
<url-pattern>/one</url-pattern>
</servlet-mapping>
index.html:
- 點選按鈕時,會呼叫getTextByAjax函式,在該函式中傳送Ajax請求。並設定回撥函式為setResponseText,當請求完成時獲取接收到的資料,把資料輸出到
<p>
標籤。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Index</title>
<script>
let xmlHttpRequest;
function getTextByAjax() {
//根據瀏覽器版本建立XMLHttpRequest物件
if(window.XMLHttpRequest){
xmlHttpRequest = new XMLHttpRequest();
}else
{
xmlHttpRequest=nexw ActiveXObject("Microsoft.XMLHTTP");
}
//建立http請求
xmlHttpRequest.open("POST", "one" ,true);
//傳送post請求,需要設定該請求頭資訊(使用get方式則可以省略)
xmlHttpRequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//設定回撥函式,當readyState改變時呼叫該函式
xmlHttpRequest.onreadystatechange = setResponseText;
//發生請求,使用的是post方式,引數資訊需通過send方法傳送
xmlHttpRequest.send("username=張三&age=25");
}
function setResponseText() {
//readyStatus未4表示請求已完成,且響應已就緒;status為200則表示請求完成且響應資料接收完畢
if(xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
//獲取伺服器端返回的文字資料
let text = xmlHttpRequest.responseText;
//將文字資料輸出在標籤中
document.getElementById("demo").innerHTML = text;
}
}
</script>
</head>
<body>
<h1>點選按鈕發生Ajax請求</h1>
<button onclick="getTextByAjax()">button</button>
<p id="demo" ></p>
</body>
</html>
執行tomcat,點選按鈕,可看到從伺服器傳送的文字資訊
且伺服器端接收到客戶端傳送的資料:
參考
https://www.w3cschool.cn/ajax/ajax-xmlhttprequest-create.html