Ajax:Asynchronous JavaScript and XML(異步JavaScript和XML)。
是指一種建立互動式、快速動态網頁應用的網頁開發技術,無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。
功能:節省使用者操作時間,提高使用者體驗,局部重新整理減少資料請求;
我們要知道,其實Ajax就是去請求背景接口拿資料的,前端拿到背景的資料後就用這些資料進行dom操作以相應的樣式輸出到頁面中。(最難的地方就是對擷取到的資料進行分析和處理并渲染到頁面上)
一、我們首先來看一個get請求的ajax流程(js代碼):
//建立一個ajax對象(類似于打開浏覽器)
var xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP'); //new ActiveXObject('Microsoft.XMLHTTP') 這個我們是對低版本IE浏覽器進行相容性處理
//使用ajax對象下面的open方法告知浏覽器請求的方式(相當于在位址欄輸入位址)
xhr.open('get','1.txt',true);
//送出(相當于按Enter鍵)
xhr.send(); //在這一步才會發送網絡請求(上面是準備工作)
//等待伺服器傳回内容
xhr.onreadystatechange = function() { // 監測readyState狀态值變化
if ( xhr.readyState == 4 ) { // readyState狀态值為4表示響應内容解析完成,可以在用戶端調用了
if ( xhr.status == 200) { //200表示http請求正确
alert( xhr.responseText ); // responseText 為背景傳回的資料
} else {
alert('出錯了,Err:' + xhr.status); //傳回錯誤響應的http狀态碼
}
}
}
二、接下來我們詳細分析一下請求ajax的流程:
1、建立一個ajax對象
(建立了ajax對象之後才能使用ajax對象下面的方法和屬性)
2、使用ajax對象下面的open()方法
open('get','url',true)方法
接收三個參數:
1.請求方式(get、post 或者其他)
2.位址(請求的背景接口位址)
3.是否異步(true為異步;false為同步)
異步:非阻塞 ajax請求的代碼不會影響後面代碼的執行(ajax請求的代碼就算沒執行完也能執行後面的代碼)
同步:阻塞 ajax請求的代碼會影響後面代碼的執行(ajax請求的關聯的代碼一定要執行完才能繼續執行後面的代碼)
(1)、get請求方式
get請求方式是通過
url?
後面的參數值傳送的(根據後端提供的接口請求參數來傳入傳輸的,多個參數之間用&連接配接)(格式要正确填寫)
(ajax參數的格式都是
參數名1=參數值1&參數名2=參數值2....
)
注意:get請求存在如下兩個問題
1.會緩存(其實我們背景資料已經變了,我們希望在重新整理位址欄的時候,頁面資料會變動。但是因為get請求方式位址不改變,内容就不會變。) 這時我們需要在url?後面連接配接一個随機數,時間戳
new Date().getTime()
(這樣就每一次通路的都是不一樣的位址)
2.中文會出現亂碼 用編碼
encodeURI()
解決
如:
(2)、post請求方式
請求資料的參數是在請求頭中(那麼資料就不能直接在url後面傳入參數了)。
xhr.open('post','post.php',true);
//一定要申明發送的資料類型(ajax沒有預設的編碼方式,表單送出有)
xhr.setRequestHeader('content-type','application/x-www-form-urlencoded');
//post請求方式,資料放在send()裡面作為參數傳遞
xhr.send('username=劉偉&age=30');
注意:post沒有緩存問題(無需設定時間戳),也不會有出現中文亂碼問題(無需編碼)
3、使用ajax對象下面的send()方法
向伺服器發送請求。
(1)、get方式,無需傳入參數
xhr.send()
(2)、post方式,需要傳入背景需要的參數
xhr.send(‘多個參數使用&分隔’)
4、等待伺服器響應并傳回資料
下面介紹ajax對象下面的屬性,當有它們的值有相關變化時,說明伺服器有相關的響應了。
readyState : ajax工作狀态(有五個值)
0 (初始化)還沒有調用open()方法
1 (載入)已調用send()方法,正在發送請求
2 (載入完成)send()方法完成,已收到全部響應内容
3 (解析)正在解析響應内容
4 (完成)響應内容解析完成,可以在用戶端調用了
onreadystatechange : 當readyState改變的時候觸發(可能會觸發很多次)
responseText : ajax請求傳回的資料内容就被存放到這個屬性下面(通過調用這個屬性就能擷取到傳回的内容,均為字元串格式)
status : 伺服器狀态,http狀态碼(容錯處理)
http狀态碼:
1xx:訓示資訊——表示請求已接收,繼續處理
2xx:成功——表示請求已經被成功接收
3xx:重定向——要完成的請求必須進行進一步操作
4xx:用戶端錯誤——請求有文法錯誤或者請求無法實作
5xx:伺服器錯誤——伺服器未能實作合法的請求
三、jq和 js的完整請求方式(隻介紹常用的文法)
我們都知道在jquery中使用ajax很友善,因為已經幫我們封裝好了。
1、jquery使用ajax:
$.ajax({
url : '請求的接口位址url',
data : '需要傳給背景的參數',
type : 'post', //預設是get
dataType:"json", // 預期伺服器傳回的資料類型,預設為json
success : function(data){ //成功擷取資料後的回調函數
// data為背景傳回的資料,通過處理data資料來渲染頁面
},
error : function(err){ //擷取資料失敗後的回調函數
// err 為背景請求錯誤後傳回的錯誤資訊
console.log(err)
}
});
2、javascript封裝ajax(隻封裝了get和post請求方式),使得像jquery的使用方式
//封裝實參覆寫形參的函數
function extend(obj1, obj2) {
for (var attr in obj2) {
obj1[attr] = obj2[attr];
}
}
// 将data中傳入的json對象轉為name=winne&age=18&like={"jk":2}&arr=[1,2]這種格式
function paramData (json) {
let str = ''
for (let key in json) {
if (typeof json[key] === 'object') {
str += `${key}=${JSON.stringify(json[key])}&`
}else{
str += `${key}=${json[key]}&`
}
}
return str.substring(0, str.length - 1)
// 上面的代碼可以用下面的代碼代替
// let resultStr = Object.keys(json).map( (key) => {
// let value = json[key]
// if (typeof value === 'object') {
// value = JSON.stringify(value)
// }
// return `${key}=${value}`
// }).join('&')
// return resultStr
}
function ajax(opt) {
defaultOpt = { //預設函數參數
"method":'get', //預設為get傳輸
"data":'', //預設沒有參數
"url":'',
"dataType":"json", //預設傳回json類型的資料
"success": function(data){} //預設擷取到資料後什麼都不做
},
"error":function(err){}
extend(defaultOpt, opt); //配置參數指派給預設參數
// 建立一個支援ajax的對象
var xhr = XMLHttpRequest
? new XMLHttpRequest()
: new ActiveXObject('Microsoft.XMLHTTP');
if (defaultOpt.method == 'get' && defaultOpt.data) { //調用預設參數
defaultOpt.url += '?' + paramData(defaultOpt.data); //get請求的完整url拼接
}
xhr.open(defaultOpt.method:toLowerCase() , defaultOpt.url, true);
if (defaultOpt.method:toLowerCase() == 'get') {
xhr.send();
} else if(defaultOpt.method:toLowerCase() == 'post'){
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send(paramData(defaultOpt.data));
}
//等待伺服器響應并傳回資料
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
defaultOpt.success && defaultOpt.success(xhr.responseText); //可變的地方用參數傳入,代碼塊就用函數傳入
} else {
defaultOpt.error&& defaultOpt.error(xhr);
// console.log('出錯了' + xhr);
}
}
}
}
// 調用js封裝好後的ajax
ajax({
url : '請求的接口位址url',
data : { // 傳給背景的參數
name: 'winne',
age: 18,
like: {jk: 2},
arr: [1, 2]
},
type : 'post', //預設是get
success : function(data){ //成功擷取資料後的回調函數
// data為背景傳回的資料,通過處理data資料來渲染頁面
// 我們最常用的是JSON.parse(data)來把字元串json轉化為真正的json來進行資料處理;
// 使用 JSON.stringfy(json)來把json資料轉化為json字元串
},
error : function(err){ //擷取資料失敗後的回調函數
// err 為背景請求錯誤後傳回的錯誤資訊
console.log(err)
}
})