Java進階學習第二十六天(JavaScript增強、AJAX基礎)
一、JavaScript增強
1、什麼是JavaScript
① 基於物件
JS本身就有一些現成的物件可供程式設計師使用,例如:Array、Math、String
② 事件驅動
JS程式碼寫好後,需要外界觸發後,方可執行,例如:單擊事件,定時執行
③ 解釋性
每次執行JS程式碼時,得需要將原始碼一行一行的解釋執行,相對編譯型語言(例如:Java、C++)執行速度相對較慢
④ 基於瀏覽器的動態互動網頁技術
如果JS嵌入到HTML中,可以不需要伺服器支援,直接由瀏覽器解釋執行;如果JS嵌入到JSP或Servlet中,必需要伺服器支援,直接由瀏覽器解釋執行
⑤ 嵌入在HTML標籤中
JS必須嵌入到一個名叫<script src="引入外部js檔案"></script>
2、JS中的三種類型
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>js型別</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> </head> <body> <!-- 1、基本型別:number,string,boolean --> <script type="text/javascript"> //num為number型別 var num = 100; //str為string型別,注意js中的string型別用''或""均可 var str = "哈哈"; //flag為boolean型別 var flag = true; </script> <!-- 2、特殊型別:null,undefined --> <script type="text/javascript"> //多個script塊中的內容,可以相互訪問 alert(flag); var person = null; var card; alert(card); //undefined不是字串,它是一種型別,如果你想判斷某個變數是否為undefined,通過如下程式碼判斷: if(card == undefined){ alert("card變數暫沒值"); }else{ alert(card); } </script> <!-- 3、複合型別:函式,物件,陣列 --> </body> </html>
3、JS中有三種定義函式的方式
<script type="text/javascript"> // 正常方式 function add(num1,num2){ return num1 + num2; } window.alert("10+20=" + add(10,20)); </script> <script type="text/javascript"> // 直接量或匿名或無名方式 var add = function(num1,num2){ return num1 + num2; } window.alert("1000+2000=" + add(1000,2000)); </script> <script type="text/javascript"> // 構造器方式:最後一個引數為函式體,每個引數都是字串型別 var add = new Function("num1","num2","return num1+num2"); window.alert("100+200=" + add(100,200)); </script>
4、JS中有四種物件
<!-- 1、內建物件:Date,Math,String,Array -->
<script type="text/javascript">
var nowStr = new Date().toLocaleString();
window.document.write(nowStr + "<br/>");
for(var i=1;i<=10;i++){
//1到9之間的隨機整數
document.write(Math.floor(Math.random()*9)+1 + "<br/>");
//document.write(Math.ceil(Math.random()*9) + "<br/>");
}
var str = "Hello你好";
var size = str.length;
alert(size);// 7
var array = new Array("語文","數學","英語",true,123);
for(var i=0;i<array.length;i++){
document.write(array[i] + " ");
}
</script>
<!-- 2、自定義物件 -->
<script type="text/javascript">
function Person(id,name,sal){
this.id = id;
this.name = name;
this.sal = sal;
}
var p = new Person(1,"張三",7000);
document.write("編號:" + p.id + "<br/>");
document.write("姓名:" + p.name + "<br/>");
document.write("薪水:" + p.sal + "<br/>");
</script>
<!-- 3、瀏覽器物件: window,document,status,location,history -->
<script type="text/javascript">
//window物件:開啟新視窗
var url = "04_images.html";
window.open(url);
</script>
<script type="text/javascript">
//status物件:將當前時間設定到狀態列中
var nowStr = new Date().toLocaleString();
window.status = nowStr;
</script>
<script type="text/javascript">
//location物件:模擬使用者在位址列輸入url訪問其它頁面的情況
var url = "04_images.html";
window.location.href = url;
</script>
<script type="text/javascript">
//history物件:演示重新整理(1是前進,-1是後退,0是不變)
window.history.go(0);
</script>
<!-- 4、ActiveX物件:ActiveXObject("Microsoft.XMLHTTP") -->
5、JS物件的屬性,方法和事件的使用 ① window.location.href ② form.submit()
<body>
<form action="04_images.html" method="POST">
<input type="button" value="提交"/>
</form>
<!-- 用JS提交表單【重要】 -->
<script type="text/javascript">
//定位提交按鈕
var inputElement = document.getElementsByTagName("input")[0];
//為提交按鈕新增單擊事件
inputElement.onclick = function(){
//定位<form>標籤,forms表示document物件中所有表單的集合,通過下標引用不同的表單,從0開始
var formElement = document.forms[0];
//提交表單,提交到action屬性指定的地方
formElement.submit();
}
</script>
</body>
③ inputElement.onblur = 函式 ④ document.createElement(“img”) ⑤ imgElement.style.width/height
6、回顧傳統Web應用請求和響應特點【顯示當前時間】 ① 請求:瀏覽器以HTTP協議的方式提交請求到伺服器 ② 響應:伺服器以HTTP協議的方式響應內容到瀏覽器 注意:HTTP是WEB大眾化非安全協議 HTTPS是WEB安全協議,是基於HTTP協議的,且加了一些加密等特殊功能,常用於線上支付,或者是需要安全性較高的網站中,例如:12306網站 HTTP請求有三個部份組成:請求行,請求頭,請求體 HTTP響應有三個部份組成:響應行,響應頭,響應體 ③ 狀態列:有明顯的進度條重新整理現象,如果伺服器響應較慢的話,進度條重新整理也會變慢,IE9等中高版本瀏覽器,有明顯轉圈圈圖示 ④ 歷史欄:會收集原來已訪問過的web頁面,進行快取 ⑤ 缺點:不需變化的大量資料,也全部重新整理,造成瀏覽器載入和處理負擔 ⑥ 可改進的地方:讓不需變化的大量資料,原封不動,不用快取到歷史欄中,無需全部重新整理,只重新整理某些需要變化的資料區域,例如:當前時間的區域
<body>
當前時間:${requestScope.nowStr}<br/>
<input id="buttonID" type="button" value="獲取當前時間"/><p/>
<script type="text/javascript">
//定位按鈕,同時新增單擊事件
document.getElementById("buttonID").onclick = function(){
//傳送請求到伺服器
var url = "${pageContext.request.contextPath}/TimeServlet";
window.location.href = url;
}
</script>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
</body>
public class TimeServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
//測試
System.out.println("GET");
//構造SimpleDateFormat物件
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//將當前日期按照指定格式輸出成字串
String nowStr = sdf.format(new Date());
//將結果繫結到request域物件中
request.setAttribute("nowStr",nowStr);
//轉發到06_time.jsp頁面
request.getRequestDispatcher("/06_time.jsp").forward(request,response);
}
}
二、AJAX基礎
1、什麼是AJAX(非同步的JS和XML)的工作原理與特點
① 什麼是同步
請求1 > 響應1 > 請求2 > 響應2>
(Web1.0時代)
② 什麼是非同步
請求1 > 請求2 > 請求3 > 響應1 > 響應2 > 響應3 >
請求1 > 響應1 > 請求2 > 請求3 > 響應2 > 響應3 >
(Web2.0時代)
專案中:Web1.0為主(整個瀏覽器重新整理),Web2.0為輔(瀏覽器區域性重新整理)
③ 什麼是AJAX
客戶端(特指PC瀏覽器)與伺服器,可以在【不必重新整理整個瀏覽器】的情況下,與伺服器進行非同步通訊的技術,即AJAX是一個【區域性重新整理】的【非同步】通訊技術。AJAX不是全新的語言,是2005年Google公司推出的一種全新【程式設計模式】,不是新的程式語言
④ 不用重新整理整個頁面便可與伺服器通訊的辦法有:
◆ Flash/ActionScript
◆ 框架Frameset
◆ iFrame(內嵌入框架)
◆ XMLHttpRequest(非IE瀏覽器)和ActiveXObject(IE瀏覽器)
背景:早在IE5時,微軟就開發出了第一個非同步通訊物件,叫ActiveXObject物件,Firefox等其它瀏覽器廠商也慢慢引入非同步通訊物件,叫XMLHttpRequest物件,IE的高版本,也將這個非同步物件取名叫XMLHttpRequest物件,但IE有向下相容問題,也可以使用ActiveXObject物件。它無需第三方jar包,現代高版本瀏覽器中內建了這個非同步通訊物件,只需通過JavaScript就可以建立
注意:所有瀏覽器中都內建了非同步物件,在預設情況下,該非同步物件並沒有創建出來
⑤ AJAX開發步驟
◆ 建立AJAX非同步物件,例如:createAJAX()
◆ 準備傳送非同步請求,例如:ajax.open(method,url)
◆ 如果是POST請求的話,一定要設定AJAX請求頭,例如:ajax.setRequestHeader();如果是GET請求的話,無需設定設定AJAX請求頭
◆ 真正傳送請求體中的資料到伺服器,例如:ajax.send()
◆ AJAX不斷的監聽服務端響應的狀態變化,例如:ajax.onreadystatechange
,後面寫一個無名處理函式
◆ 在無名處理函式中,獲取AJAX的資料後,按照DOM規則,用JS語言來操作Web頁面
⑥ AJAX適合用在什麼地方
AJAX【適合】不用來傳遞大量資料,而只用來【傳遞少量資料】,在使用者的【體驗】上,【更加人性化】。
AJAX是一個和伺服器無關的技術,即伺服器可使用:JavaEE,.NET,PHP等等這些技術,AJAX只管向伺服器傳送請求,同時只管接收伺服器的HTML或XML或JSON載體響應服務端不能使用轉發或重定向到web頁面,因為這樣會起瀏覽器全面重新整理,即只能以流的方式響應給瀏覽器
2、AJAX應用 ① 無需重新整理整個Web頁面顯示伺服器響應的當前時間
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());
//注意:在Web2.0時代,即非同步方式下不能用轉發或重定向。因為:轉發或重定向會引起瀏覽器全部重新整理,而不是區域性重新整理,所以得用以輸出流的方式將伺服器的結果輸出到瀏覽器
//以流的方式將結果響應到AJAX非同步物件中
response.setContentType("text/html;charset=UTF-8");
PrintWriter pw = response.getWriter();
pw.write(nowStr);
pw.flush();
pw.close();
}
}
<body>
當前時間:<span id="time"></span><br/>
<input id="buttonID" type="button" value="獲取當前時間"/><p/>
<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">
//定位button按鈕,同時新增單擊事件
document.getElementById("buttonID").onclick = function(){
//1、建立AJAX非同步物件
var ajax = createAJAX();
//2、AJAX準備傳送請求
var method = "GET";
var url = "${pageContext.request.contextPath}/AjaxTimeServlet?time=" + new Date().getTime();
ajax.open(method,url);
//3、真正傳送請求體的資料到伺服器,如果請求體中無資料的話,就用null表示
ajax.send(null);
//-------------------------------------------------------------等待
//4、AJAX非同步物件不斷監聽伺服器響應的狀態【0-1-2-3-4】
//一定要狀態變化後,才可觸發function(){}函式
//如果狀態永遠是4-4-4-4-4,是不會觸發function(){}函式的
//以下這個函式是伺服器來觸發的,不是程式設計師觸發的,這和onclick是不一樣的
ajax.onreadystatechange = function(){
//如果狀態碼為4的話
if(ajax.readyState == 4){
//如果響應碼為200的話
if(ajax.status == 200){
//5、從AJAX非同步物件中獲取伺服器響應的HTML資料
var nowStr = ajax.responseText;
//6、將結果按照DOM規則,動態新增到web頁面指定的標籤中
var spanElement = document.getElementById("time");
spanElement.innerHTML = nowStr;
}
}
}
}
</script>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字靜態文字<br/>
</body>
② 基於HTML,以GET或POST方式,檢查註冊使用者名稱是否在資料庫中已存在
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");//Tomcat伺服器是以ISO編碼
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();
}
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();
}
}
<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);
var ajax = createAJAX();
var method = "GET";
var url = "${pageContext.request.contextPath}/UserServlet?time="+new Date().getTime()+"&username=" + username;
ajax.open(method,url);
ajax.send(null);
//--------------------------------------------------------等待
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){
if(ajax.status == 200){
var tip = ajax.responseText;
document.getElementById("resID").innerHTML = tip;
}
}
}
}
}
</script>
</body>
<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;
var ajax = createAJAX();
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");
var content = "username=" + username;
ajax.send(content);
//===========================================等待
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){
if(ajax.status == 200){
var tip = ajax.responseText;
// 建立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>
③ 基於XML,以POST方式,完成省份-城市二級下拉聯動
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("</root>");
pw.flush();
pw.close();
}
}
<body>
<select id="provinceID" style="width:111px">
<option>選擇省份</option>
<option>江蘇</option>
<option>上海</option>
</select>
<select id="cityID" style="width:111px">
<option>選擇城市</option>
</select>
<script type="text/javascript">
//定位省份下拉框,同時新增內容改變事件
document.getElementById("provinceID").onchange = function(){
//清空城市下拉框中的內容,除第一項外
var cityElement = document.getElementById("cityID");
cityElement.options.length = 1;
//獲取選中option標籤的索引號,從0開始
var index = this.selectedIndex;
//定位選中的option標籤
var optionElement = this[index];
//獲取選中的option標籤中的內容,即省份
var province = optionElement.innerHTML;
//如果選中的內容不是"選擇省份"
if("選擇省份" != province){
var ajax = createAJAX();
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");
var content = "province=" + province;
ajax.send(content);
//---------------------------------等待
ajax.onreadystatechange = function(){
if(ajax.readyState == 4){
if(ajax.status == 200){
// 從AJAX非同步物件中獲取伺服器響應的xml文件
var xmlDocument = ajax.responseXML;
// 按照DOM規則,解析XML文件
var cityElementArray = xmlDocument.getElementsByTagName("city");
var size = cityElementArray.length;
for(var i=0;i<size;i++){
// innerHTML只能用在html/jsp中,不能用在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>
④ 驗證碼檢查
3、XMLHttpRequest物件常用事件、方法和屬性
① 事件
ajax.onreadystatechange
:表示AJAX非同步物件不斷監聽伺服器狀態的一個變化過程(0-1-2-3-4),其中4是核心,只有狀態變化了該事件才會觸發;它是由伺服器程式觸發,不是程式設計師觸發;後面通常跟著一個無名函式。
② 方法
◆ ajax.open(method,url,可選的boolean值)
:AJAX非同步物件準備傳送非同步請求
◇ method:以什麼方式傳送(提交方式),常用的用GET或POST,大小寫不敏感
◇ url:傳送到什麼地方去,常用到Servlet、Struts2、SpringMVC、PHP、.NET;只需要伺服器以流的方式返回資料即可,即AJAX與伺服器技術無關
◇ 可選的boolean值:預設值為true,表示AJAX物件以【非同步】的方式提交到服務端,如果設定為false,表示AJAX物件以【同步】的方式提交到服務端
◆ ajax.setRequestHeader("content-type","application/x-www-form-urlencoded")
:表示將請求體中的內容,按照UTF-8的方式進行編碼,只針對POST請求有效
◆ ajax.send(content)
:AJAX非同步物件真正傳送非同步請求
content:表示HTTP【請求體】中的內容
◇ 如果是GET方式:content = null,如果強行傳值到伺服器,服務端收不到,返回NULL
◇ 如果是POST方式:content != null,例如:username=jack&password=123&role=admin
③ 屬性
◆ ajax.readyState
ajax.readyState==0
:表示AJAX非同步物件已建立好,但還沒有呼叫open()方法
ajax.readyState==1
:表示AJAX非同步物件已呼叫open()方法,但還沒有呼叫send()方法
ajax.readyState==2
:表示AJAX非同步物件已呼叫send()方法,但請求還沒有到達伺服器端
ajax.readyState==3
:表示服務端已接收到AJAX非同步物件的請求,正在處理響應中。。。
ajax.readyState==4
:表示AJAX非同步物件已經完完全全接收到了伺服器的響應信 息,但接收到的資料不一定都正確
上述5種狀態不是所有瀏覽器都相同,但狀態4每種瀏覽器都相同
◆ ajax.status==200
:表示AJAX非同步物件接收到響應碼,如果是200的話,表示一切正常
◆ ajax.responseText
:表示從AJAX非同步物件中獲取HTML載體中的資料
◆ ajax.responseXML
:表示從AJAX非同步物件中獲取XML載體中的資料
4、資料載體 ① HTML ◆ 優點:服務端響應的是普通html字串,無需JS解析,配合innerHTML屬性效率高 ◆ 缺點:如果需要更新WEB頁面中的很多處地方,HTML不太方便,同時innerHTML屬性不是DOM的標準,不能操作XML 注意:innerHTML在xml中不能使用,用firstChild.nodeValue替代 ◆ 適合:小量資料載體,且只更新在web頁面中的一個地方 ② XML ◆ 優點:是種通用的普通字串格式,任何技術都能解析,標籤名可以任意,使用DOM標準規則能夠解析XML的任何部分 ◆ 缺點:XML檔案格式相當嚴格,出錯後,responseXML屬性返回NULL,如果XML檔案過長,導致解析效率低下 ◆ 適合:大量具有層次資料載體 ③ JSON + struts2框架 兼備HTML和XML的特點