前后端交互-jQuery中的Ajax

jQuery中封裝的Ajax請求比我們自己封裝的更好用,下面我們就學(xué)習(xí)一下。

一. jQuery中的方法

1 - $.ajax()方法

① 發(fā)送Ajax請求

$.ajax({
    type: 'get',
    url: 'http://www.example.com',
    // 因?yàn)樵O(shè)置了下面的參數(shù),無論傳遞的是哪種格式的,最后都會轉(zhuǎn)成'屬性=屬性值&'字符串格式的
    contentType: 'application/x-www-form-urlencoded',
    // 傳遞的參數(shù) 
    // 也可以是 data: 'name=zhangsan&age=20' 字符串格式的,
    data: { name: 'zhangsan', age: '20' },
    // 請求發(fā)送之前調(diào)用,比如參數(shù)格式的校驗(yàn),或者loading框的顯示
    beforeSend: function () {
        // 如果返回false,那么請求就不會被發(fā)送
        return false
    },
    // 請求成功
    // response為服務(wù)器端返回的數(shù)據(jù),方法內(nèi)部會自動將json字符串轉(zhuǎn)換為json對象
    success: function (response) {},
    // 請求失敗
    error: function (xhr) {}
});
{
    // 傳遞json格式的參數(shù)
    contentType: 'application/json'
    // 然后data中傳遞json字符串
    data: JSON.stringify({name: 'zhangsan', age: '20'})
}

② 發(fā)送jsonp請求

$.ajax({
    url: 'http://www.example.com',
    // 指定當(dāng)前發(fā)送jsonp請求
    dataType: 'jsonp',
    // 修改callback參數(shù)名稱
    jsonp: 'cb',
    // 指定函數(shù)名稱(一般不使用,我們就使用下面的sucess就好了)
    jsonCallback: 'fnName',
    // 接收服務(wù)器端返回的數(shù)據(jù)
    success: function (response) {} 
})

解釋:以前我們寫<script src="http://localhost:3001/better?callback=fn"></script> jsonp就是替換其中的callback為cb,jsonCallback就是替換fn為fnName。

2 - serialize方法

前面我們說了,當(dāng)我們使用Ajax技術(shù)傳遞參數(shù)的時候,還需要獲取表單控件以及獲取表單控件的值,然后將值按照指定的格式進(jìn)行字符串拼接,然后再傳遞給服務(wù)端,特別繁瑣,之前我們使用的是FormData 對象,但是FormData對象是html5中提供的,存在兼容性問題。

下面我們介紹jQuery中提供的serialize方法,可以解決這個問題。

serialize方法作用:將表單中的數(shù)據(jù)自動拼接成字符串類型的參數(shù)。

var params = $('#form').serialize();
// name=zhangsan&age=30

示例代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>serialize方法說明</title>
</head>
<body>
    <form id="form">
        <input type="text" name="username">
        <input type="password" name="password">
        <input type="submit" value="提交">
    </form>
    <script src="/js/jquery.min.js"></script>
    <script type="text/javascript">
        $('#form').on('submit', function () {
            // 將表單內(nèi)容拼接成字符串類型的參數(shù)
            var params = $('#form').serialize();
            console.log(params)  // name=zhangsan&age=30

            // 將表單內(nèi)容轉(zhuǎn)成對象類型,方法實(shí)現(xiàn)在下面
            var objArr = serializeObject($(this));

            // 阻止表單的提交行為
            return false;
        });

        // 將表單中用戶輸入的內(nèi)容轉(zhuǎn)換為對象類型(這個方法在后面項(xiàng)目中會頻繁使用)
        function serializeObject (obj) {
            // 處理結(jié)果對象
            var result = {};
      
            // jQuery提供的方法
            // 將表單中用戶輸入的內(nèi)容轉(zhuǎn)換成數(shù)組,數(shù)組中存的是對象,對象有name和value兩個值
            // [{name: 'username', value: '用戶輸入的內(nèi)容'}, {name: 'password', value: '123456'}]
            var params = obj.serializeArray();

            // 循環(huán)數(shù)組 將數(shù)組轉(zhuǎn)換為對象類型
            $.each(params, function (index, value) {
                result[value.name] = value.value;
            })
            // 將處理的結(jié)果返回到函數(shù)外部
            return result;
        }
    </script>
</body>
</html>

3 - $.get、$.post方法

作用:$.get方法用于發(fā)送get請求,$.post方法用于發(fā)送post請求。

// 參數(shù)1:請求地址 
// 參數(shù)2:參數(shù),可以是對象也可以是'屬性=屬性值&'格式的字符串
// 參數(shù)3:成功回調(diào)函數(shù)
$.get('http://www.example.com', {name: 'zhangsan', age: 30}, function (response) {}) $.post('http://www.example.com', {name: 'lisi', age: 22}, function (response) {})

二. jQuery中的Ajax案例:Todolist

1 - 為todo數(shù)據(jù)庫添加賬號

  1. 使用mongo命令進(jìn)入mongodb數(shù)據(jù)庫(如果失敗,使用sudo mongo
  2. 使用use admin命令進(jìn)入到admin數(shù)據(jù)中
  3. 使用db.auth('root', 'root')命令登錄數(shù)據(jù)庫(這個超級管理員賬號是以前我們設(shè)置的)
  4. 使用use todo命令切換到todo數(shù)據(jù)庫(如果有就直接進(jìn)入,沒有就創(chuàng)建之后進(jìn)入)
  5. 使用db.createUser({user: 'itcast', pwd: 'itcast', roles: ['readWrite']})創(chuàng)建todo數(shù)據(jù)庫賬號
  6. 使用exit命令退出mongodo數(shù)據(jù)庫

2 - 展示任務(wù)列表

  1. 準(zhǔn)備一個放置任務(wù)列表的數(shù)組
  2. 向服務(wù)器端發(fā)送請求,獲取已存在的任務(wù)
  3. 將已存在的任務(wù)存儲在任務(wù)列表數(shù)組中
  4. 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)顯示在頁面中

3 - 添加任務(wù)

  1. 為文本框綁定鍵盤抬起事件,在事件處理函數(shù)中判斷當(dāng)前用戶敲擊的是否是回車鍵
  2. 當(dāng)用戶敲擊回車鍵的時候,判斷用戶在文本框中是否輸入了任務(wù)名稱
  3. 向服務(wù)器端發(fā)送請求,將用戶輸入的任務(wù)名稱添加到數(shù)據(jù)庫中,同時將任務(wù)添加到任務(wù)數(shù)組中
  4. 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)顯示在頁面中

4 - 刪除任務(wù)

  1. 為刪除按鈕添加點(diǎn)擊事件
  2. 在事件處理函數(shù)中獲取到要刪任務(wù)的id
  3. 向服務(wù)器端發(fā)送請求,根據(jù)ID刪除任務(wù),同時將任務(wù)數(shù)組中的相同任務(wù)刪除
  4. 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)重新顯示在頁面中

5 - 更改任務(wù)狀態(tài)

  1. 為任務(wù)復(fù)選框添加onchange事件
  2. 在事件處理函數(shù)中獲取復(fù)選框是否選中
  3. 向服務(wù)器端發(fā)送請求,將當(dāng)前復(fù)選框的是否選中狀態(tài)提交到服務(wù)器端
  4. 將任務(wù)狀態(tài)同時也更新到任務(wù)列表數(shù)組中
  5. 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)重新顯示在頁面中并且根據(jù)任務(wù)是否完成為li元素添加completed類名

6 - 修改任務(wù)名稱

  1. 為任務(wù)名稱外層的label標(biāo)簽添加雙擊事件,同時為當(dāng)前任務(wù)外層的li標(biāo)簽添加editing類名,開啟編輯狀態(tài)
  2. 將任務(wù)名稱顯示在文本框中并讓文本框獲取焦點(diǎn)
  3. 當(dāng)文本框離開焦點(diǎn)時,將用戶在文本框中輸入值提交到服務(wù)器端,并且將最新的任務(wù)名稱更新到任務(wù)列表數(shù)組中
  4. 使用模板引擎重新渲染頁面中的任務(wù)列表。

7 - 計(jì)算未完成任務(wù)數(shù)量

  1. 準(zhǔn)備一個用于存儲未完成任務(wù)數(shù)量的變量
  2. 將未完成任務(wù)從任務(wù)數(shù)組中過濾出來
  3. 將過濾結(jié)果數(shù)組的長度賦值給任務(wù)數(shù)量變量
  4. 將結(jié)果更新到頁面中

8 - 顯示未完成任務(wù)

  1. 為active按鈕添加點(diǎn)擊事件
  2. 從任務(wù)列表數(shù)組中將未完成任務(wù)過濾出來
  3. 使用模板引擎將過濾結(jié)果顯示在頁面中

9 - 清除已完成任務(wù)

  1. 為clear completed按鈕添加點(diǎn)擊事件
  2. 向服務(wù)器端發(fā)送請求將數(shù)據(jù)庫中的已完成任務(wù)刪除掉
  3. 將任務(wù)列表中的已完成任務(wù)刪除調(diào)用
  4. 使用模板引擎將任務(wù)列表中的最后結(jié)果顯示在頁面中

10 - 項(xiàng)目運(yùn)行步驟

代碼地址:https://github.com/iamkata/Ajax-in-jQuery

  1. cd到項(xiàng)目目錄,執(zhí)行npm install下載第三方模塊
  2. 執(zhí)行node app.js啟動服務(wù)器
  3. 瀏覽器輸入http://localhost:3000/todo/index.html訪問項(xiàng)目

結(jié)果如下:

三. jQuery中Ajax全局事件

1 - 全局事件

只要頁面中有Ajax請求被發(fā)送,對應(yīng)的全局事件就會被觸發(fā)。jQuery規(guī)定,Ajax全局事件一定要綁定在document身上。

.ajaxStart()     // 當(dāng)請求開始發(fā)送時觸發(fā)
.ajaxComplete()  // 當(dāng)請求完成時觸發(fā)

2 - NProgress 進(jìn)度條

官宣:納米級進(jìn)度條,使用逼真的涓流動畫來告訴用戶正在發(fā)生的事情!

<link rel='stylesheet' href='nprogress.css'/>
<script src='nprogress.js'></script>
NProgress.start();  // 進(jìn)度條開始運(yùn)動 
NProgress.done();   // 進(jìn)度條結(jié)束運(yùn)動

3 - 示例代碼

// 當(dāng)頁面中有ajax請求發(fā)送時觸發(fā)
$(document).on('ajaxStart', function () {
    // 顯示進(jìn)度條
    NProgress.start() 
})

// 當(dāng)頁面中有ajax請求完成時觸發(fā)
$(document).on('ajaxComplete', function () {
    // 完成進(jìn)度條
    NProgress.done() 
})

補(bǔ)充一. RESTful 風(fēng)格的 API

1 - 傳統(tǒng)請求地址回顧

GET http://www.example.com/getUsers         // 獲取用戶列表
GET http://www.example.com/getUser?id=1     // 比如獲取某一個用戶的信息
POST http://www.example.com/modifyUser      // 修改用戶信息
GET http://www.example.com/deleteUser?id=1  // 刪除用戶信息

上面的請求,使用起來沒什么問題,但是在語義上不明,比如最后一個刪除用戶信息,使用了deleteUser?id=1,但是卻使用了獲取用戶信息的GET請求方式,這是矛盾的。

2 - RESTful API 概述

RESTful API一套關(guān)于設(shè)計(jì)請求的規(guī)范。

  • POST: 添加數(shù)據(jù)(增)
  • DELETE: 刪除數(shù)據(jù)(刪)
  • PUT: 更新數(shù)據(jù)(改)
  • GET: 獲取數(shù)據(jù)(查)

注意:傳統(tǒng)的html表單提交是不支持PUT和DELETE請求方式的,但是在Ajax中是支持的,所以現(xiàn)在我們才來學(xué)習(xí)它。

3 - RESTful API 的實(shí)現(xiàn)

注意:

  1. RESTful風(fēng)格的API中使用名詞不使用動詞。
  2. 請求地址需要和操作的集合保持一致,比如需要操作用戶集合users,那么請求地址就要是/users,如下:
users => /users
articles => /articles 

示例代碼:

服務(wù)端app.js代碼:

// 獲取用戶列表信息
app.get('/users', (req, res) => {
    res.send('當(dāng)前是獲取用戶列表信息的路由');
});

// 獲取某一個用戶具體信息的路由
// :id主要是用來占位的,代表客戶端傳過來的一個參數(shù)
// 以前我們獲取'屬性名=屬性值&'這樣的參數(shù)時,我們是使用req.query獲取的
// :id這樣的參數(shù)我們使用req.params.id獲取
app.get('/users/:id', (req, res) => {
    // 獲取客戶端傳遞過來的用戶id
    const id = req.params.id;
    res.send(`當(dāng)前我們是在獲取id為${id}用戶信息`);
});

// 刪除某一個用戶
app.delete('/users/:id', (req, res) => {
    // 獲取客戶端傳遞過來的用戶id
    const id = req.params.id;
    res.send(`當(dāng)前我們是在刪除id為${id}用戶信息`);
});

// 修改某一個用戶的信息
app.put('/users/:id', (req, res) => {
    // 獲取客戶端傳遞過來的用戶id
    const id = req.params.id;
    res.send(`當(dāng)前我們是在修改id為${id}用戶信息`);
});

客戶端html代碼:

// 獲取用戶列表信息
$.ajax({
    type: 'get',
    url: '/users',
    success: function (response) {
        console.log(response)
    }
})

// 獲取id為1的用戶信息
$.ajax({
    type: 'get',
    url: '/users/1',
    success: function (response) {
        console.log(response)
    }
})

// 刪除id為10的用戶信息
$.ajax({
    type: 'delete',
    url: '/users/10',
    success: function (response) {
        console.log(response)
    }
})

// 修改id為10的用戶信息
$.ajax({
    type: 'put',
    url: '/users/10',
    success: function (response) {
        console.log(response)
    }
})

補(bǔ)充二. XML 基礎(chǔ)

1 - XML是什么

XML 的全稱是 extensible markup language,代表可擴(kuò)展標(biāo)記語言,它和html一樣都是標(biāo)記語言,它的作用是傳輸和存儲數(shù)據(jù)。

html中有好多預(yù)定義標(biāo)簽,比如p、div、body等,在XML中沒有預(yù)定義標(biāo)簽的,所有的標(biāo)簽都是開發(fā)者定義的。

<students>
    <student>
        <sid>001</sid>
        <name>張三</name>
    </student>
    <student>
        <sid>002</sid>
        <name>王二丫</name>
    </student>
</students>

如上XML中保存了兩個學(xué)生的信息,有學(xué)生的id(sid)和學(xué)生的姓名(name)。

XML和html的區(qū)別:

  1. XML是用來傳輸和存儲數(shù)據(jù)的,它的關(guān)注點(diǎn)是在數(shù)據(jù)的內(nèi)容上。
  2. html是用來展示數(shù)據(jù)的,它的關(guān)注點(diǎn)在數(shù)據(jù)的外觀。

2 - XML DOM

XML DOM 即 XML 文檔對象模型,是 w3c 組織定義的一套操作 XML 文檔對象的API。瀏覽器會將 XML 文檔解析成文檔對象模型。

那么服務(wù)器端如何傳XML類型的數(shù)據(jù)?客戶端如何接收XML類型的數(shù)據(jù)呢?示例代碼如下:

服務(wù)器端app.js代碼:

app.get('/xml', (req, res) => {
    // 告訴客戶端,返回的類型是XML的
    res.header('content-type', 'text/xml');
    res.send('<message><title>消息標(biāo)題</title><content>消息內(nèi)容</content></message>')
});

客戶端html代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <button id="btn">發(fā)送請求</button>
    <div id="container"></div>
    <script type="text/javascript">
        var btn = document.getElementById('btn');
        var container = document.getElementById('container');

        btn.onclick = function () {
            var xhr = new XMLHttpRequest();
            // 發(fā)送Ajax請求
            xhr.open('get', '/xml');
            xhr.send();
            xhr.onload = function () {
                // 當(dāng)服務(wù)器端返回的是XML類型的數(shù)據(jù)時,我們就不能使用xhr.responseText來接收服務(wù)器端返回的數(shù)據(jù)了
                // 我們要使用xhr.responseXML 獲取服務(wù)器端返回的xml數(shù)據(jù)
                var xmlDocument = xhr.responseXML;
                // getElementsByTagName這是XML的API,用來獲取XML文檔樹中的第一個title標(biāo)簽
                // 然后通過innerHTML獲取他的值
                var title = xmlDocument.getElementsByTagName('title')[0].innerHTML;
                container.innerHTML = title;
            }
        }
    </script>
</body>
</html>

代碼地址:https://github.com/iamkata/Ajax-in-jQuery

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

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

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