文章目錄
一、Ajax
1.1 定義
Ajax,是 Asynchronous JavaScript + XML 的簡寫。這種技術能夠想服務器請求額外的數據而無須卸載頁面(即刷新),會帶來更好的用戶體驗。、
1.2 同步、異步現象
同步現象:客戶端發送請求到服務器端,當服務器返回響應之前,客戶端都處於等待卡死狀態
異步現象:客戶端發送請求到服務器端,無論服務器是否返回響應,客戶端都可以隨意做其他事情,不會被卡死
1.3 Ajax的運行原理
頁面發起請求,會將請求發送給瀏覽器內核中的Ajax引擎,Ajax引擎會提交請求到服務器端,在這段時間裏,客戶端可以任意進行任意操作,直到服務器端將數據返回給Ajax引擎後,會觸發你設置的事件,從而執行自定義的JS邏輯代碼完成某種頁面功能。
二、XMLHttpRequest
2.1 定義
Ajax 的技術核心是 XMLHttpRequest 對象(簡稱XHR),這是由微軟首先引入的一個特性,其他瀏覽器提供商後來都提供了相同的實現。
在 XHR 出現之前,Ajax 式的通信必須藉助一些 hack 手段來實現,大多數是使用隱藏的框架或內嵌框架。XHR 的出現,提供了向服務器發送請求和解析服務器響應提供了流暢的接口。能夠以異步方式從服務器獲取更多的信息,這就意味着,用戶只要觸發某一事件,在不刷新網頁的情況下,更新服務器最新的數據。
雖然 Ajax 中的 x 代表的是 XML,但 Ajax 通信和數據格式無關,也就是說這種技術不一定使用 XML。
2.2 不同瀏覽器對於XMR的支持
IE7+、Firefox、Opera、Chrome 和Safari 都支持原生的XHR 對象,在這些瀏覽器中創建 XHR 對象可以直接實例化 XMLHttpRequest 即可。
var xhr = new XMLHttpRequest();
如果是 IE6 及以下,那麼我們必須還需要使用 ActiveX 對象通過 MSXML 庫來實現。在低版本IE 瀏覽器可能會遇到三種不同版本的 XHR 對象,即MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0。我們可以編寫一個函數。
// 得到ajax對象,不同瀏覽器方式可能不同,但格式固定
function GetXmlHttpObject() {
var xmlHttp=null;
try{
// Firefox, Opera 8.0+, Safari
xmlHttp = new XMLHttpRequest()
} catch (e){
// Internet Explorer
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e){
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
2.3 使用XHR 對象步驟
JS 原生的 Ajax 其實就是圍繞瀏覽器內內置的 Ajax 引擎對象進行學習的,要使用 JS 原生的 Ajax 完成異步操作,有如下幾個步驟:
- 創建 Ajax 引擎對象
- 爲 Ajax 引擎對象綁定監聽(監聽服務器已將數據響應給引擎)
- 綁定提交地址
- 發送請求
- 接受響應數據
以下爲詳細講解:
在使用XHR 對象時,先必須調用open()方法,它接受三個參數:要發送的請求類型(get、post)、請求的URL 和表示是否異步(false 同步,true異步)。
GET 請求是最常見的請求類型,最常用於向服務器查詢某些信息。必要時,可以將查詢字符串參數追加到URL 的末尾,以便提交給服務器。
xhr.open('get', 'demo.php?rand=' + Math.random() + '&name=Koo', true);
而發送POST 請求的數據,字符串參數不會跟在URL 的尾巴上,而是通過send()方法向服務器提交數據。
xhr.send('name=Lee&age=100');
一般來說,向服務器發送POST 請求由於解析機制的原因,需要進行特別的處理。因爲POST 請求和Web 表單提交是不同的,需要使用XHR來模仿表單提交。
// 這行代碼放在 open()和 send()之間
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
open() 方法並不會真正發送請求,而只是啓動一個請求以備發送。還需通過 send() 方法進行發送請求,send() 方法接受一個參數,作爲請求主體發送的數據。如果不需要則必須填 null。
執行 send() 方法之後,請求就會發送到服務器上。
xhr.send(null); //發送請求
當請求發送到服務器端,收到響應後,響應的數據會自動填充 XHR 對象的屬性。一共有四個屬性:
接受響應之後,第一步檢查 status 屬性,以確定響應已經成功返回。一般而已HTTP 狀態代碼爲200 作爲成功的標誌。
使用異步調用的時候,需要觸發 xhr.onreadystatechange 事件,然後檢測 readyState 屬性即可。這個屬性有五個值:
最後獲取返回數據傳輸的值xhr.responseText
即可。
三、後端獲取系統時間在前端展示(相當於雙十一時淘寶頁面上的某商品交易額實時變動)
index.jsp
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<p id="ppp"></p>
<script type="text/javascript">
// 每2毫秒執行一次該函數,獲取實時時間
setInterval(function(){
ajaxFun();
},2);
function ajaxFun(){
var xhr = new XMLHttpRequest();
// open()方法並不會真正發送請求,而只是啓動一個請求以備發送
// post請求唯一的方式就是表單提交
xhr.open('post','/day_0911_web8/ajaxTextServlet',true);
// 一般來說,向服務器發送POST 請求由於解析機制的原因,需要進行特別的處理。
// 因爲POST請求和Web 表單提交是不同的,需要使用XHR來模仿表單提交
// 這行代碼就使用在post方式提交“騙”過服務器是以表單的方式提交過去
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
// 發送請求,send()方法接受一個參數,作爲請求主體發送的數據
// 如果不需要則必須填null。執行send()方法之後,請求就會發送到服務器上
xhr.send("name=rose");
//xhr.open('get','/day_0911_web8/ajaxTextServlet?name=jack',true);
//xhr.send(null);
// 使用異步調用的時候,需要觸發xhr.onreadystatechange 事件,然後檢測readyState屬性即可
xhr.onreadystatechange=function(){
if(xhr.status==200){ // 服務器的響應狀態碼
// 說明服務器正常響應了
if(xhr.readyState==4){ // ajax的狀態碼
// ajax正常拿到數據了
var date = xhr.responseText;
ppp.innerHTML = date;
}
}
}
}
</script>
</body>
</html>
AjaxTextServlet.java
package com.java.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AjaxTextServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// String name = req.getParameter("name");
// PrintWriter writer = resp.getWriter();
// writer.write("你好!"+name);
PrintWriter writer = resp.getWriter();
writer.write(System.currentTimeMillis()+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
效果:
四、註冊用戶名時判斷該用戶名是否已存在
regist.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>註冊</title>
</head>
<body>
<form action="/day_0910_web7/insertCustomerServlet" method="post" onsubmit="return check()" >
用戶名稱:<input type="text" name="cu_name" id="name1" /><br />
用戶電話:<input type="text" name="cu_phone" /><br />
用戶性別:
<select name="cu_gender">
<option value="1" selected>男</option>
<option value="0">女</option>
</select><br />
用戶地址:<input type="text" name="cu_address" /><br />
<input type="submit" value="註冊" /><a href="/day_0910_web7">已經註冊了</a>
</form>
<script type="text/javascript" src="js/regist.js"></script>
</body>
</html>
CheckCustomerNameServlet.java
package com.ishopn.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ishopn.controller.CustomerController;
public class CheckCustomerNameServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
String cu_name = req.getParameter("cu_name");
int c = new CustomerController().getCountCustomerByName(cu_name);
PrintWriter writer = resp.getWriter();
writer.write(c+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
regist.js
var flag=true;
var inputs=document.getElementsByTagName("input");
function check(){
for(var i=0;i<inputs.length;i++){
if(inputs[i].value==null || inputs[i].value.trim().length==0){
flag=false;
alert("所有信息不能爲空!");
break;
}
}
return flag;
}
// 用戶名輸入框失去焦點時觸發該函數
name1.onblur=function(){
var t = this.value;
if(t.length>0){
var xhr = new XMLHttpRequest();
xhr.open('post','/day_0910_web7/checkCustomerNameServlet',true);
//這行代碼就使用在post方式提交 “騙”過服務器是以表單的方式提交過去的
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("cu_name="+t);
xhr.onreadystatechange=function(){
if(xhr.status==200){ //服務器的響應狀態碼
// 說明服務器正常相應了
if(xhr.readyState==4){ //ajax的狀態碼
var c = xhr.responseText;
if(c>0){
alert("用戶名已經存在");
flag=false;
}else{
flag=true;
}
}
}
}
}
}
效果:
推薦一篇更詳細的博客:https://blog.csdn.net/wu_Duo/article/details/52627193