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ù)庫添加賬號
- 使用
mongo命令進(jìn)入mongodb數(shù)據(jù)庫(如果失敗,使用sudo mongo) - 使用
use admin命令進(jìn)入到admin數(shù)據(jù)中 - 使用
db.auth('root', 'root')命令登錄數(shù)據(jù)庫(這個超級管理員賬號是以前我們設(shè)置的) - 使用
use todo命令切換到todo數(shù)據(jù)庫(如果有就直接進(jìn)入,沒有就創(chuàng)建之后進(jìn)入) - 使用
db.createUser({user: 'itcast', pwd: 'itcast', roles: ['readWrite']})創(chuàng)建todo數(shù)據(jù)庫賬號 - 使用
exit命令退出mongodo數(shù)據(jù)庫
2 - 展示任務(wù)列表
- 準(zhǔn)備一個放置任務(wù)列表的數(shù)組
- 向服務(wù)器端發(fā)送請求,獲取已存在的任務(wù)
- 將已存在的任務(wù)存儲在任務(wù)列表數(shù)組中
- 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)顯示在頁面中
3 - 添加任務(wù)
- 為文本框綁定鍵盤抬起事件,在事件處理函數(shù)中判斷當(dāng)前用戶敲擊的是否是回車鍵
- 當(dāng)用戶敲擊回車鍵的時候,判斷用戶在文本框中是否輸入了任務(wù)名稱
- 向服務(wù)器端發(fā)送請求,將用戶輸入的任務(wù)名稱添加到數(shù)據(jù)庫中,同時將任務(wù)添加到任務(wù)數(shù)組中
- 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)顯示在頁面中
4 - 刪除任務(wù)
- 為刪除按鈕添加點(diǎn)擊事件
- 在事件處理函數(shù)中獲取到要刪任務(wù)的id
- 向服務(wù)器端發(fā)送請求,根據(jù)ID刪除任務(wù),同時將任務(wù)數(shù)組中的相同任務(wù)刪除
- 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)重新顯示在頁面中
5 - 更改任務(wù)狀態(tài)
- 為任務(wù)復(fù)選框添加onchange事件
- 在事件處理函數(shù)中獲取復(fù)選框是否選中
- 向服務(wù)器端發(fā)送請求,將當(dāng)前復(fù)選框的是否選中狀態(tài)提交到服務(wù)器端
- 將任務(wù)狀態(tài)同時也更新到任務(wù)列表數(shù)組中
- 通過模板引擎將任務(wù)列表數(shù)組中的任務(wù)重新顯示在頁面中并且根據(jù)任務(wù)是否完成為li元素添加completed類名
6 - 修改任務(wù)名稱
- 為任務(wù)名稱外層的label標(biāo)簽添加雙擊事件,同時為當(dāng)前任務(wù)外層的li標(biāo)簽添加editing類名,開啟編輯狀態(tài)
- 將任務(wù)名稱顯示在文本框中并讓文本框獲取焦點(diǎn)
- 當(dāng)文本框離開焦點(diǎn)時,將用戶在文本框中輸入值提交到服務(wù)器端,并且將最新的任務(wù)名稱更新到任務(wù)列表數(shù)組中
- 使用模板引擎重新渲染頁面中的任務(wù)列表。
7 - 計(jì)算未完成任務(wù)數(shù)量
- 準(zhǔn)備一個用于存儲未完成任務(wù)數(shù)量的變量
- 將未完成任務(wù)從任務(wù)數(shù)組中過濾出來
- 將過濾結(jié)果數(shù)組的長度賦值給任務(wù)數(shù)量變量
- 將結(jié)果更新到頁面中
8 - 顯示未完成任務(wù)
- 為active按鈕添加點(diǎn)擊事件
- 從任務(wù)列表數(shù)組中將未完成任務(wù)過濾出來
- 使用模板引擎將過濾結(jié)果顯示在頁面中
9 - 清除已完成任務(wù)
- 為clear completed按鈕添加點(diǎn)擊事件
- 向服務(wù)器端發(fā)送請求將數(shù)據(jù)庫中的已完成任務(wù)刪除掉
- 將任務(wù)列表中的已完成任務(wù)刪除調(diào)用
- 使用模板引擎將任務(wù)列表中的最后結(jié)果顯示在頁面中
10 - 項(xiàng)目運(yùn)行步驟
代碼地址:https://github.com/iamkata/Ajax-in-jQuery
- cd到項(xiàng)目目錄,執(zhí)行
npm install下載第三方模塊 - 執(zhí)行
node app.js啟動服務(wù)器 - 瀏覽器輸入
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)
- POST:http://www.example.com/users 添加用戶數(shù)據(jù)
- DELETE:http://www.example.com/users/1 刪除用戶ID為1的用戶信息
- PUT:http://www.example.com/users/1 修改用戶ID為1的用戶信息
- GET:http://www.example.com/users 獲取用戶列表數(shù)據(jù)
- GET:http://www.example.com/users/1 獲取用戶ID為1的用戶信息
注意:
- RESTful風(fēng)格的API中使用名詞不使用動詞。
- 請求地址需要和操作的集合保持一致,比如需要操作用戶集合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ū)別:
- XML是用來傳輸和存儲數(shù)據(jù)的,它的關(guān)注點(diǎn)是在數(shù)據(jù)的內(nèi)容上。
- 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>