前端 -- Ajax

一、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

發佈了18 篇原創文章 · 獲贊 25 · 訪問量 952
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章