1. 程式人生 > >JavaScript增強Ajax基礎

JavaScript增強Ajax基礎

  • 什麼是AJAX:

       客戶端(特指PC瀏覽器)與伺服器,可以在【不必重新整理整個瀏覽器】的情況下,與伺服器進行非同步通訊的技術,AJAX是一個【區域性重新整理】的【非同步】通訊技術。

  • Ajax例項:

1.無需重新整理整個Web頁面顯示伺服器響應的當前時間

//瀏覽器端

//1.Ajax的建立

<script type="text/javascript">
		//建立AJAX非同步物件
		function createAJAX(){
			var ajax = null;
			try{
				//如果IE5=IE12的話
				ajax = new ActiveXObject("microsoft.xmlhttp");
			}catch(e1){
				try{
					//如果是非IE的話
					ajax = new XMLHttpRequest();
				}catch(e2){
					alert("你的瀏覽器中不支援非同步物件,請換瀏覽器");
				}
			}
			return ajax;
		}
</script>


<script type="text/javascript">
		document.getElementById("buttonID").onclick = function(){
			//NO1)建立AJAX非同步物件
			var ajax = createAJAX();
			//NO2)準備傳送請求
			var method = "GET";
            //在後面加上時間毫秒 主要是為了相容老版IE
			var url = "${pageContext.request.contextPath}/AjaxTimeServlet?time=" + new Date().getTime();
			ajax.open(method,url);
			//NO3)真正傳送請求體的資料到伺服器,如果請求體中無資料的話,就用null表示
			ajax.send(null);
			
			//------Ajax請求已經發送,等待後臺處理 返回xml格式返回資料----------
		
			//響應正確 並且完全響應,進行回撥處理
			ajax.onreadystatechange = function(){
				//如果狀態碼為4的話
				if(ajax.readyState == 4){
					//如果響應碼為200的話
					if(ajax.status == 200){
						//NO5)從AJAX非同步物件中獲取伺服器響應的HTML資料
						var nowStr = ajax.responseText;
						
						//NO6)將結果按照DOM規則,動態新增到web頁面指定的標籤中
						var spanElement = document.getElementById("time");
						spanElement.innerHTML = nowStr;
					}
				}
			} 
			
		}
</script>


//後臺服務端處理程式碼:

/**
 * 無需重新整理整個Web頁面顯示伺服器響應的當前時間
 * @author AdminTC
 */
public class AjaxTimeServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String nowStr = sdf.format(new Date());
		
		//以流的方式將結果響應到AJAX非同步物件中
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.write(nowStr);
		pw.flush();
		pw.close();
	}
}


   2.Ajax使用者名稱校驗提示(文字提示)

//客戶端頁面


<html>
  <head>
    <title>基於HTML,以GET或POST方式,檢查註冊使用者名稱是否在資料庫中已存在</title>
  </head>
  <body>
	
	<form>
		使用者名稱[GET]:<input id="usernameID" type="text" name="username" maxlength="4"/>
		游標移出後,立即檢查結果
	</form>
	<hr/>
	<span id="resID"></span>
	
	<script type="text/javascript">
		//建立AJAX非同步物件,即XMLHttpRequest
		function createAJAX(){
			var ajax = null;
			try{
				ajax = new ActiveXObject("microsoft.xmlhttp");
			}catch(e1){
				try{
					ajax = new XMLHttpRequest();
				}catch(e2){
					alert("你的瀏覽器不支援ajax,請更換瀏覽器");
				}
			}
			return ajax;
		}
	</script>
	
	
	<script type="text/javascript">
		//定位文字框,同時提供焦點失去事件
		document.getElementById("usernameID").onblur = function(){
			//獲取文字框中輸入的值
			var username = this.value;
			//如果使用者沒有填內容
			if(username.length == 0){
				//提示 
				document.getElementById("resID").innerHTML = "使用者名稱必填";
			}else{
				//對漢字進行UTF-8(U8)的編碼
				username = encodeURI(username);
				//NO1)
				var ajax = createAJAX();
				//NO2)
				var method = "GET";
                //GET請求資料直接拼接在請求的URL後
				var url = "${pageContext.request.contextPath}/UserServlet?time="+new Date().getTime()+"&username=" + username;
				ajax.open(method,url);
				//NO3)
				ajax.send(null);
				
				//--------------------------------------------------------等待
				
				//NO4)
				ajax.onreadystatechange = function(){
					if(ajax.readyState == 4){
						if(ajax.status == 200){
							//NO5)
							var tip = ajax.responseText;
							//NO6)
							document.getElementById("resID").innerHTML = tip;
						}
					}
				}
			}
		}
	</script>
	
  </body>
</html>




//服務端程式碼:

/**
 * 基於HTML,以GET或POST方式,檢查註冊使用者名稱是否在資料庫中已存在 
 * @author AdminTC
 */
public class UserServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		String username = request.getParameter("username");
		byte[] buf = username.getBytes("ISO8859-1");
		username = new String(buf,"UTF-8");
		System.out.println("username=" + username);
		String tip = "<font color='green'>可以註冊</font>";
		if("傑克".equals(username)){
			tip = "<font color='red'>該使用者已存在</font>";
		}
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.write(tip);
		pw.flush();
		pw.close();
	}
}

總結:上述兩種非同步都是通過GET方式請求,請求資料內容放在URL後,GET請求方式需要對編碼(中文)進行相應處理。

基於POST提交方式的Ajax請求: 

1.檢查註冊使用者名稱是否在資料庫中已存在(圖片提示)

//客戶端

<html>
  <head>
    <title>基於HTML,以GET或POST方式,檢查註冊使用者名稱是否在資料庫中已存在</title>
	<!-- 引入外部js文字 -->
    <script type="text/javascript" src="js/ajax.js"></script>
  </head>
  <body>
	
	
	使用者名稱[POST]:<input id="usernameID" type="text" maxlength="4"/>
	<span id="resID">
		<!-- 
		<img src="tip變數" width="12px" height="12px"/>
		-->
	</span>
	
	
	<hr/>

	
	<script type="text/javascript">
		document.getElementById("usernameID").onblur = function(){
			var username = this.value;//傑克
			//NO1)
            //建立物件引自"js/ajax.js"
			var ajax = createAJAX();
			//NO2)
			var method = "POST";
			var url = "${pageContext.request.contextPath}/UserServlet?time="+new Date().getTime();
			ajax.open(method,url);
			//設定AJAX請求頭為POST,他會將請求體中的漢字自動進行UTF-8的編碼
			ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");
			//NO3)
			var content = "username=" + username;
			ajax.send(content);
			
			
			//===========================================等待
			
			
			//NO4)
			ajax.onreadystatechange = function(){
				if(ajax.readyState == 4){
					if(ajax.status == 200){
						//NO5)
						var tip = ajax.responseText;
					
						//NO6)
						//建立img標籤
						var imgElement = document.createElement("img");
						//設定img標籤的src/width/height的屬性值
						imgElement.src = tip;
						imgElement.style.width = "12px";
						imgElement.style.height = "12px";
						//定位span標籤
						var spanElement = document.getElementById("resID");
						//清空span標籤中的內容
						spanElement.innerHTML = "";
						//將img標籤加入到span標籤中
						spanElement.appendChild(imgElement);
					}
				}
			}
		}
	</script>
	
	
	<!-- 
	<form action="" method="" enctype="application/x-www-form-urlencoded"></form>
	-->

  </body>
</html>


//後臺處理程式碼

/**
 * 基於HTML,以GET或POST方式,檢查註冊使用者名稱是否在資料庫中已存在 
 * @author AdminTC
 */
public class UserServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		doPost(request,response);
	}

public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String username = request.getParameter("username");
		System.out.println("username=" + username);
		
		String tip = "images/MsgSent.gif";
		if("傑克".equals(username)){
			tip = "images/MsgError.gif";
		}
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		pw.write(tip);
		pw.flush();
		pw.close();
	}
}

 2.基於XML,以POST方式,完成省份-城市二級下拉聯動

//客戶端

<html>
  <head>
    <title>基於XML,以POST方式,完成省份-城市二級下拉聯動</title>
    <script type="text/javascript" src="js/ajax.js"></script>
  </head>
  <body>
		
	<select id="provinceID" style="width:111px">
		<option>選擇省份</option>
		<option>湖南</option>
		<option>廣東</option>
	</select>	
	&nbsp;&nbsp;&nbsp;
	<select id="cityID" style="width:111px">
		<option>選擇城市</option>
	</select>	
	
	<script type="text/javascript">
		//定位省份下拉框,同時新增內容改變事件
		document.getElementById("provinceID").onchange = function(){
			//清空城市下拉框中的內容,除第一項外
			var cityElement = document.getElementById("cityID");
            //主要每次append城市節點時會直接往後追加,所以每次點選省份後 先清除再放
			cityElement.options.length = 1;

			//獲取選中option標籤的索引號,從0開始			
			var index = this.selectedIndex; 	
			//定位選中的option標籤
			var optionElement = this[index];
			//獲取選中的option標籤中的內容,即省份
			var province = optionElement.innerHTML;
			//如果選中的內容不是"選擇省份"
			if("選擇省份" != province){
				//NO1)
				var ajax = createAJAX();
				//NO2)
				var method = "POST";
				var url = "${pageContext.request.contextPath}/ProvinceCityServlet?time="+new Date().getTime();
				ajax.open(method,url);
				//設定AJAX請求頭
				ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");
				//NO3)
				var content = "province=" + province;
				ajax.send(content);
				
				//---------------------------------等待
				
				//NO4)
				ajax.onreadystatechange = function(){
					if(ajax.readyState == 4){
						if(ajax.status == 200){
							//NO5)從AJAX非同步物件中獲取伺服器響應的xml文件
							var xmlDocument = ajax.responseXML;
							
							//NO6)按照DOM規則,解析XML文件
								
							var cityElementArray = xmlDocument.getElementsByTagName("city");	
							var size = cityElementArray.length;
							for(var i=0;i<size;i++){
			  //innerHTML只能用在html/jsp中,不能用在xml中,xml解析應當是獲取每一個節點值
								var city = cityElementArray[i].firstChild.nodeValue;
								//<option></option>
								var optionElement = document.createElement("option");	
								//<option>廣州</option>
								optionElement.innerHTML = city;
								//<select><option>廣州</option></select>
                                //每一個節點值 放入城市下拉框中
								cityElement.appendChild(optionElement);
							}
						}
					}
				}
			}
		}
	</script>
	
  </body>
</html>




後臺處理程式碼:

/**
 * 基於XML,以POST方式,完成省份-城市二級下拉聯動
 * @author AdminTC
 */
public class ProvinceCityServlet extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String province = request.getParameter("province");
		
		//通知AJAX非同步物件,伺服器響應的資料為xml格式的
		response.setContentType("text/xml;charset=UTF-8");
		//獲取字元輸出流
		PrintWriter pw = response.getWriter();
		
		pw.write("<?xml version='1.0' encoding='UTF-8'?>");
		pw.write("<root>");
								
		
		if("廣東".equals(province)){
			pw.write("<city>廣州</city>");
			pw.write("<city>深圳</city>");
			pw.write("<city>中山</city>");
		}else if("湖南".equals(province)){
			pw.write("<city>長沙</city>");
			pw.write("<city>株洲</city>");
			pw.write("<city>湘潭</city>");
			pw.write("<city>岳陽</city>");
		}
		
		
		pw.write("</root>");    //組裝成List<String> 的形式
		pw.flush();
		pw.close();
	}
}

總結:POST提交方式,需要在 ajax.open(method,url) 和  ajax.send(content)中間設定請求頭,將請求體中的漢子自動進行UTF-8的編碼轉換。

設定內容為:ajax.setRequestHeader("content-type","application/x-www-form-urlencoded");

          ;