AJAX技術(shù)

AJAX

一、介紹

AJAX : Asychronous Javascript And XML,指異步JavaScript及XML。是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。

AJAX 是一種用于創(chuàng)建快速動(dòng)態(tài)網(wǎng)頁的技術(shù)。

通過在后臺(tái)與服務(wù)器進(jìn)行少量數(shù)據(jù)交換,AJAX 可以使網(wǎng)頁實(shí)現(xiàn)異步更新。這意味著可以在不重新加載整個(gè)網(wǎng)頁的情況下,對(duì)網(wǎng)頁的某部分進(jìn)行更新。

傳統(tǒng)的網(wǎng)頁(不使用 AJAX)如果需要更新內(nèi)容,必須重載整個(gè)網(wǎng)頁頁面。

二、使用AJAX

1. JS原生AJAX[了解]

通過查詢W3C文檔使用JS原生AJAX。

一般可分為五步:

1. 創(chuàng)建AJAX對(duì)象
2. 綁定監(jiān)聽事件---監(jiān)聽服務(wù)器是否響應(yīng)數(shù)據(jù)了
3. 綁定請(qǐng)求的服務(wù)器地址
4. 發(fā)送請(qǐng)求
5. 服務(wù)器響應(yīng)成功執(zhí)行的函數(shù)

//1.創(chuàng)建對(duì)象
xmlhttp = new XMLHttpRequest();
//2.綁定監(jiān)聽事件---監(jiān)聽服務(wù)器是否響應(yīng)
xmlhttp.onreadystatechange = function() {
    //5.服務(wù)器響應(yīng)成功執(zhí)行的函數(shù)
    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
        alert(xmlhttp.responseText);
    }
}
//3.綁定請(qǐng)求路徑
xmlhttp.open("GET", "${pageContext.request.contextPath}/demo", true);
//4.發(fā)送請(qǐng)求
xmlhttp.send();
  • 服務(wù)器狀態(tài)碼(readyState、status):

      readyState :
    
      0 :  XMLHttpRequest對(duì)象沒有完成初始化。即:剛剛創(chuàng)建。
    
      1 :  XMLHttpRequest對(duì)象開始發(fā)送請(qǐng)求.調(diào)用了open方法,但還沒有調(diào)用send方法,請(qǐng)求還未發(fā)出。
    
      2 :  XMLHttpRequest對(duì)象的請(qǐng)求發(fā)送完成。但服務(wù)器還未響應(yīng)
    
      3 :  XMLHttpRequest對(duì)象開始讀取響應(yīng),還沒有結(jié)束收到了所有的響應(yīng)消息頭,但正文還沒有完全收到
    
      4 :  XMLHttpRequest對(duì)象讀取響應(yīng)結(jié)束
    
    
      status :
    
      200 :   OK .服務(wù)器接收到請(qǐng)求并已響應(yīng)。
      400 :   無法找到請(qǐng)求的資源。
      403 :   沒有訪問權(quán)限
      404 :   訪問的資源不存在
      500 :   服務(wù)器內(nèi)部錯(cuò)誤
    

2. JQurey的AJAX【重點(diǎn)】

2.1 get方式

<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript">
    $.get(
        url,    //請(qǐng)求的地址路徑
        params,     //發(fā)送到服務(wù)器的參數(shù)
        function(){},   //回調(diào)函數(shù),服務(wù)器響應(yīng)成功后執(zhí)行的函數(shù)
        type        //一般為json和text,默認(rèn)text。服務(wù)器返回的數(shù)據(jù)格式
    );
</script>

例如:

$.get(
    "${pageContext.request.contextPath}/demo2",//url,請(qǐng)求訪問的路徑
    {name:"zhangsan",age:20},//要傳遞到服務(wù)器的參數(shù)
    function(data) {    //響應(yīng)成功后執(zhí)行的函數(shù),data是服務(wù)器返回的數(shù)據(jù)
        alert(data);
    },
    "text"http://服務(wù)器返回的數(shù)據(jù)格式
);  

2.2 post方式

與get方式一樣,只需要把$.get()改為$.post()即可

<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script type = "text/javascript">
    $.post(
        url,    //請(qǐng)求的地址路徑
        params,     //發(fā)送到服務(wù)器的參數(shù)
        function(){},   //回調(diào)函數(shù),服務(wù)器響應(yīng)成功后執(zhí)行的函數(shù)
        type        //一般為json和text,默認(rèn)text。服務(wù)器返回的數(shù)據(jù)格式
    );
</script>

例如:

$.post(
    "${pageContext.request.contextPath}/demo2",//url,請(qǐng)求訪問的路徑
    {"name":"yom","age":10},//要傳遞到服務(wù)器的參數(shù)
    function(data) {    //響應(yīng)成功后執(zhí)行的函數(shù),data是服務(wù)器返回的數(shù)據(jù)
        alert(data);
    },
    "text"http://服務(wù)器返回的數(shù)據(jù)格式
);

2.3 ajax方式

get與post是ajax方式的簡(jiǎn)化,用get和post方式可以節(jié)省不少代碼。
但ajax的功能更多,他可以指定是否同步或異步,而get和post方式就不能改變,只能異步請(qǐng)求。
  • JQuery的包的路徑一定要導(dǎo)入并且要正確否則就會(huì)失敗,js文件放在web-content下新建的js文件夾中,路徑前不要加'/'
  • ajax方式和get與post的異步請(qǐng)求格式有個(gè)小區(qū)別,就是ajax的格式是json格式,前后都有大括號(hào),中間為key:value的鍵值對(duì)形式。兩個(gè)鍵值對(duì)之間以逗號(hào)隔開。

    <script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>

    <input type="button" value="ajax(ajax方式異步請(qǐng)求)" onclick="fn()" />

    <script type="text/javascript">
        function fn() {
            $.ajax({
                type : "POST",//請(qǐng)求方式
                async : true,//是否異步,true為異步,false為同步
                url : "${pageContext.request.contextPath}/demo3",//請(qǐng)求的服務(wù)器路徑
                data : "name=小明",//請(qǐng)求傳遞的參數(shù)
                success : function(data) {//響應(yīng)成功后執(zhí)行的函數(shù),這里的data是指服務(wù)器傳遞回來的數(shù)據(jù)
                    alert(data.name);
                    alert(data.age);
                },
                dataType : "json" //服務(wù)器響應(yīng)的數(shù)據(jù)格式
            });
        }
    </script>   

三、案例

1. 案例一:異步校驗(yàn)用戶名是否已經(jīng)存在

思路:

1. 準(zhǔn)備用戶數(shù)據(jù)庫,與注冊(cè)頁面。
2. 搭建開發(fā)環(huán)境,數(shù)據(jù)庫相關(guān)的jar包:驅(qū)動(dòng),c3p0,配置文件,dbutils。
3. 新建工程,創(chuàng)建包結(jié)構(gòu):web-service-dao
4. 具體實(shí)現(xiàn)。servlet---service---dao數(shù)據(jù)庫查詢并返回結(jié)果.
    1. 在jsp頁面獲取到用戶輸入的用戶名
    2. 用異步請(qǐng)求的技術(shù)AJAX將用戶輸入的用戶名提交到服務(wù)器。
    3. dao層查詢,返回一個(gè)User對(duì)象。
    4. 新建ResultBean的bean類,servlet判斷User對(duì)象是否為空設(shè)置ResultBean的值。
        這個(gè)對(duì)象存儲(chǔ)了返回的消息。將其封裝成json響應(yīng)回客戶端。
5. 客戶端解析json數(shù)據(jù)。

代碼實(shí)現(xiàn):

1. 準(zhǔn)備數(shù)據(jù)庫與注冊(cè)頁面

2. 準(zhǔn)備開發(fā)需要的jar包與配置文件,工具類JDBCUtils

public class JDBCUtils {
    private static DataSource ds = new ComboPooledDataSource();// c3p0默認(rèn)配置獲取連接池
    // 可以認(rèn)為是與線程綁定的獲取連接的Map集合
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

    // 獲取連接池的方法
    public static DataSource getDataSource() {
        return ds;
    }

    // 通過連接池獲取連接的方法
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    // 從ThreadLocal中獲取與線程綁定的連接Connection
    public static Connection getConnectionTL() throws SQLException {
        Connection connection = threadLocal.get();
        if (connection == null) {
            threadLocal.set(getConnection());
            connection = threadLocal.get();
        }
        return connection;

    }

    // 開啟事務(wù)的方法
    public static void startTransaction() throws SQLException {
        Connection connection = getConnectionTL();
        connection.setAutoCommit(false);
    }

    // 提交事務(wù)并釋放資源的方法
    public static void commitAndRelease() throws SQLException {
        Connection connection = getConnectionTL();
        connection.rollback();
        if (connection != null) {
            connection.close();
            // 這里為什么connection關(guān)閉后還要設(shè)置為null呢?
            // 因?yàn)樵陉P(guān)閉close的時(shí)候可能出現(xiàn)了異常導(dǎo)致關(guān)閉失敗,這個(gè)時(shí)候connection就處于一種未知的狀態(tài),這種情況下垃圾回收器gc就不能將他回收
            // 因此在后面將它設(shè)為null,這樣即使出現(xiàn)異常也能被垃圾回收器關(guān)閉
            connection = null;
        }
        threadLocal.remove();
    }

    // 回滾事務(wù)并釋放資源的方法
    public static void rollbackAndRelease() throws SQLException {
        Connection connection = getConnectionTL();
        if (connection != null) {
            connection.close();
            connection = null;
        }
        threadLocal.remove();
    }
}

3. 新建工程,創(chuàng)建包結(jié)構(gòu):web-service-dao

4. 后臺(tái)功能的具體實(shí)現(xiàn)

1. 在jsp頁面獲取用戶輸入框,綁定失去焦點(diǎn)事件,用異步請(qǐng)求將獲取到的用戶名發(fā)送到服務(wù)器端。

使用jquery的ajax前一定要導(dǎo)入jquery。

<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
    $(function(){   //頁面加載完成時(shí)間
        //獲取輸入用戶名的輸入框?qū)ο蟛槠浣壎╫nblur事件
        $("#username").blur(function() {
            //獲取到用戶輸入的用戶名
            var $username = $("#username").val();
            //使用AJAX技術(shù)將獲取到的用戶名傳到服務(wù)器后臺(tái)進(jìn)行查詢
            $.post(
                "${pageContext.request.contextPath}/checkUsername",//url,發(fā)送請(qǐng)求到服務(wù)器的地址
                "username="+$username,//請(qǐng)求的參數(shù)
                function(data) {//服務(wù)器響應(yīng)成功后執(zhí)行的函數(shù)
                    //data為服務(wù)器響應(yīng)回的json數(shù)據(jù),將其解析在用戶名輸入框的下方,獲取到該div標(biāo)簽對(duì)象
                    $("#checkUsername").html(data.message);                                 
                    if(data.isExist) {
                        $("#checkUsername").css("color","red");
                    }else {
                        $("#checkUsername").css("color","green");
                    }
                },
                "json"http://服務(wù)器響應(yīng)的數(shù)據(jù)格式
            );
        });
    });
</script>   



2. 服務(wù)器端servlet接收異步請(qǐng)求發(fā)送過來的參數(shù)(用戶輸入的用戶名),將它傳到service層處理,返回查詢到的用戶User。
在servlet層對(duì)User進(jìn)行判斷,根據(jù)User的是否為null設(shè)置bean類ResultBean中的isExsit與message值。將bean類寫回客戶端。

// 編碼
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// 獲取異步請(qǐng)求AJAX傳遞的參數(shù)username
String username = request.getParameter("username");

// 調(diào)用業(yè)務(wù)層
try {
    CheckNameService service = new CheckNameService();
    User user = service.checkUsername(username);

    // 在這里使用一個(gè)存儲(chǔ)用戶是否存在boolean和傳回客戶端信息的bean內(nèi)來封裝數(shù)據(jù)
    ResultBean resultBean = new ResultBean();
    // 判斷用戶名為username的用戶是否存在,給resultBean賦值
    if (user == null) {
        resultBean.setExist(false);// 說明用戶名不存在
        resultBean.setMessage("用戶名不存在,可以使用");
    } else {
        resultBean.setExist(true);// 說明用戶存在
        resultBean.setMessage("用戶名已存在!");
    }

    // 將封裝后的resultBean轉(zhuǎn)化成json格式的字符串,這里要使用到Gson工具包
    Gson gson = new Gson();
    String json = gson.toJson(resultBean);
    System.out.println(json);
    // 將封裝好的json字符串寫回客戶端解析
    response.getWriter().write(json);

} catch (SQLException e) {
    e.printStackTrace();
}


3. 創(chuàng)建servlet層用到的兩個(gè)bean類:User與ResultBean

4. service層調(diào)用dao層。
    CheckNameDAO dao = new CheckNameDAO();
    return dao.checkUsername(username); 

5. dao層連接數(shù)據(jù)庫查詢是否存在該用戶名的用戶。

    QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
    String sql = "select * from user where name=?";
    return runner.query(sql, new BeanHandler<User>(User.class),username);

6. dao層返回值為User,servlet層判斷是否存在設(shè)置ResultBean的值,客戶端接收resultBean的json值進(jìn)行解析,添加到對(duì)應(yīng)要顯示的位置即可。
這在前面的代碼中也已經(jīng)顯示了。

5. 效果圖

img01.png
img02.png

2. 案例二: 站內(nèi)異步搜索

需求:模仿淘寶搜索寶貝,每次輸入一個(gè)關(guān)鍵字時(shí),異步請(qǐng)求服務(wù)器,去數(shù)據(jù)庫進(jìn)行模糊查詢,將查詢到的商品名返回到客戶端顯示。

分析:

1. 在要添加該功能的div標(biāo)簽后添加一個(gè)div標(biāo)簽,完成布局。
2. 獲取到搜索框的對(duì)象,對(duì)其進(jìn)行mouseup監(jiān)聽,每次觸發(fā)都發(fā)起異步請(qǐng)求,異步請(qǐng)求將搜索框內(nèi)的數(shù)據(jù)傳送到服務(wù)器查詢。
3. 服務(wù)器servlet接收到異步請(qǐng)求ajax發(fā)送過來的參數(shù),將其傳遞到service--dao進(jìn)行模糊查詢,返回查詢到的商品集合,
    將其封裝成json字符串響應(yīng)回客戶端。
4. 客戶端接收到響應(yīng)的數(shù)據(jù),解析json并將其添加到添加的div標(biāo)簽內(nèi)。

2.1 jsp布局

在用戶的search搜索輸入框的div中添加一個(gè)div,為搜索聯(lián)想框.
css屬性:
    1. display為none,不可見,當(dāng)輸入關(guān)鍵字keyup監(jiān)聽時(shí)將其設(shè)置為block可見。
    2. position:absolute。設(shè)置該div是獨(dú)立的,防止對(duì)父標(biāo)簽div的布局影響。
    3. z-index:999.設(shè)置z軸上的優(yōu)先級(jí),數(shù)字越大布局越在上方。
    
<div id="returnKey" style="display:none;width: 196px;height: 80px;position: 
    absolute;background-color: white;z-index: 999" ></div>


獲取到搜索輸入框元素,為搜索輸入框添加鍵盤監(jiān)聽事件:
通過監(jiān)聽事件,用戶每次輸入關(guān)鍵字,松開鍵時(shí)觸發(fā)searchKeyWords()方法。
該方法獲取到用戶輸入的關(guān)鍵字?jǐn)?shù)據(jù),利用異步請(qǐng)求ajax技術(shù)將其發(fā)送到服務(wù)器查詢數(shù)據(jù)庫。
function中的data為服務(wù)器返回的商品List集合,遍歷集合,在添加的搜索聯(lián)想框div中添加div標(biāo)簽,將商品的名字一一添加進(jìn)去。

//用戶輸入搜索關(guān)鍵字產(chǎn)生的聯(lián)想
function searchKeyWords() {
    $("#returnKey").css("display","block");
    //獲取搜索框的輸入的關(guān)鍵字
    var $keyWords = $("#searchWords").val();
    //使用異步請(qǐng)求將獲取到的關(guān)鍵字發(fā)送到服務(wù)器進(jìn)行查詢
    if($keyWords!="") {
        $.post(
            "${pageContext.request.contextPath}/searchWords",//url
            "keyWords="+$keyWords,//請(qǐng)求發(fā)送的參數(shù)
            function(data) {//服務(wù)器響應(yīng)成功后執(zhí)行的函數(shù)
                //將服務(wù)器響應(yīng)回的數(shù)據(jù)解析寫到id為returnKey的div中
                var resultString = "";
                for (var i = 0; i < data.length; i++) {
                    resultString += "<div onclick='insertContent(this)' onmouseover='changeColor(this)' onmouseout='backColor(this)' style='margin-left: 5px;margin-top: 3px'>"+data[i].pname+"</div>";
                }
                $("#returnKey").html(resultString);
            },
            "json"http://服務(wù)器返回的數(shù)據(jù)格式
            );
        }
    }
</script>   

2.2 服務(wù)器Servlet處理異步請(qǐng)求發(fā)送過來的關(guān)鍵字

servlet將請(qǐng)求的參數(shù)keyWords傳至service層/dao層在數(shù)據(jù)庫中模糊查詢,將查詢到的商品數(shù)據(jù),轉(zhuǎn)換為json字符串寫回客戶端。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //編碼
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/html;charset=UTF-8");
    //獲取ajax傳遞過來的參數(shù)keywords
    String keyWords = request.getParameter("keyWords");
    try {
        //調(diào)用業(yè)務(wù)邏輯層,將獲取到的keywords傳遞到service---dao
        SearchKeyWordsService service = new SearchKeyWordsService();
        List<Product> list =  service.searchKeyWords(keyWords);
        //將返回的list商品數(shù)據(jù)轉(zhuǎn)化為json格式的字符串傳回客戶端
        Gson gson = new Gson();
        String json = gson.toJson(list);
        
        //寫回客戶端
        response.getWriter().write(json);
    } catch (Exception e) {
        e.printStackTrace();
    }

2.3 service層

SearchKeyWordsDAO dao = new SearchKeyWordsDAO();
return dao.searchKeyWords(keyWords);

2.4 dao層

sql語句limit限制查詢的條數(shù),這樣就能控制顯示的聯(lián)想數(shù)量

QueryRunner runner = new QueryRunner(JDBCUtils.getDataSource());
String sql = "select * from products where pname like ? limit 3"; 
return runner.query(sql, new BeanListHandler<Product>(Product.class), "%"+keyWords.trim()+"%");

2.5 jsp界面優(yōu)化

  1. 用戶選擇關(guān)鍵字后,將該關(guān)鍵字添加到輸入框中
    1. 關(guān)鍵字添加到輸入框后,聯(lián)想框的display屬性再次設(shè)置為none
  2. 用戶將鼠標(biāo)移至聯(lián)想條目時(shí),變色,移出時(shí),恢復(fù)

    <script type="text/javascript">
    //鼠標(biāo)移到條目上方時(shí)給搜索條目增加背景色
    function changeColor(obj) {
        $(obj).css("background-color","#ccc");
    }
    //鼠標(biāo)移出條目上方時(shí)給搜索條目還原背景色
    function backColor(obj) {
        $(obj).css("background","white");
    }
    
    //用戶點(diǎn)擊聯(lián)想商品名稱時(shí),將該商品名添加到搜索框中
    function insertContent(obj) {
        var $pname = $(obj).html();//獲得搜索聯(lián)想的商品名
        //點(diǎn)擊時(shí)將該商品名加入到搜索輸入框中
        $("#searchWords").val($pname);
        //隱藏聯(lián)想框
        $("#returnKey").css("display","none");
    }
    </script>

***
####~~~歡迎指正交流...
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • AJAX 原生js操作ajax 1.創(chuàng)建XMLHttpRequest對(duì)象 var xhr = new XMLHtt...
    碧玉含香閱讀 3,574評(píng)論 0 7
  • 一、什么是ajax? AJAX(AsynchronousJavaScriptandXML):異步的JavaScri...
    猿基地閱讀 726評(píng)論 0 1
  • Ajax 1.什么是Ajax? Ajax(Asychronous javascript and xml),中文翻譯...
    草鞋弟閱讀 367評(píng)論 0 0
  • 本文詳細(xì)介紹了 XMLHttpRequest 相關(guān)知識(shí),涉及內(nèi)容: AJAX、XMLHTTP、XMLHttpReq...
    semlinker閱讀 13,999評(píng)論 2 18
  • 想要了解什么是ajax先從幾個(gè)問題開始:1.ajax怎么同時(shí)發(fā)送多個(gè)請(qǐng)求? 在ajax應(yīng)用中,通常一個(gè)頁面要同時(shí)發(fā)...
    想做一個(gè)畫家閱讀 456評(píng)論 0 0

友情鏈接更多精彩內(nèi)容