ajax datatype_小白跟我一起学习ajax
點(diǎn)擊上方藍(lán)字關(guān)注我們!
?學(xué)習(xí)鏈接 https://zhuanlan.zhihu.com/p/114501873
?一、AJAX
- ajax 全名 Asynchronous JavaScript and XML
- 是前后臺交互的能力
- 也就是我們客戶端給服務(wù)端發(fā)送消息的工具,以及接受響應(yīng)的工具
- 異步請求數(shù)據(jù)的web開發(fā)技術(shù)
AJAX 的優(yōu)勢
- 不需要插件的支持,原生 js 就可以使用
- 用戶體驗(yàn)好(不需要刷新頁面就可以更新數(shù)據(jù))
- 減輕服務(wù)端和帶寬的負(fù)擔(dān)
- 缺點(diǎn):搜索引擎的支持度不夠,因?yàn)閿?shù)據(jù)都不在頁面上,搜索引擎搜索不到
AJAX 的使用
- 在 js 中有內(nèi)置的構(gòu)造函數(shù)來創(chuàng)建 ajax 對象
- 創(chuàng)建 ajax 對象以后,我們就使用 ajax 對象的方法去發(fā)送請求和接受響應(yīng)
創(chuàng)建一個(gè) ajax 對象
//?IE9及以上const?xhr?=?new?XMLHttpRequest()
//?IE9以下
const?xhr?=?new?ActiveXObject('Mricosoft.XMLHTTP')
- 上面就是有了一個(gè) ajax 對象
- 我們就可以使用這個(gè) xhr 對象來發(fā)送 ajax 請求了
配置鏈接信息
const?xhr?=?new?XMLHttpRequest()//?xhr?對象中的?open?方法是來配置請求信息的
//?第一個(gè)參數(shù)是本次請求的請求方式?get?/?post?/?put?/?...
//?第二個(gè)參數(shù)是本次請求的?url?
//?第三個(gè)參數(shù)是本次請求是否異步,默認(rèn)?true?表示異步,false?表示同步
//?xhr.open('請求方式',?'請求地址',?是否異步)
xhr.open('get',?'https://api.github.com/users/sunshineyanghui')
- 上面的代碼執(zhí)行完畢以后,本次請求的基本配置信息就寫完了
發(fā)送請求
const?xhr?=?new?XMLHttpRequest()xhr.open('get',?'https://api.github.com/users/sunshineyanghui')
//?使用?xhr?對象中的?send?方法來發(fā)送請求
xhr.send()
- 上面代碼是把配置好信息的 ajax 對象發(fā)送到服務(wù)端
一個(gè)基本的 ajax 請求
- 一個(gè)最基本的 ajax 請求就是上面三步
- 但是光有上面的三個(gè)步驟,我們確實(shí)能把請求發(fā)送的到服務(wù)端
- 如果服務(wù)端正常的話,響應(yīng)也能回到客戶端
- 但是我們拿不到響應(yīng)
- 如果想拿到響應(yīng),我們有兩個(gè)前提條件
1.本次 HTTP 請求是成功的,也就是我們之前說的 http 狀態(tài)碼為 200 ~ 299
2.ajax 對象也有自己的狀態(tài)碼,用來表示本次 ajax 請求中各個(gè)階段
ajax 狀態(tài)碼
ajax 狀態(tài)碼 - xhr.readyState
是用來表示一個(gè) ajax 請求的全部過程中的某一個(gè)狀態(tài)
- readyState === 0:表示未初始化完成,也就是 open 方法還沒有執(zhí)行
- readyState === 1:表示配置信息已經(jīng)完成,也就是執(zhí)行完 open 之后
- readyState === 2:表示 send 方法已經(jīng)執(zhí)行完成
- readyState === 3:表示正在解析響應(yīng)內(nèi)容
- readyState === 4:表示響應(yīng)內(nèi)容已經(jīng)解析完畢,可以在客戶端使用了
這個(gè)時(shí)候我們就會發(fā)現(xiàn),當(dāng)一個(gè) ajax 請求的全部過程中,只有當(dāng) readyState === 4 的時(shí)候,我們才可以正常使用服務(wù)端給我們的數(shù)據(jù)
所以,配合 http 狀態(tài)碼為 200 ~ 299
- 一個(gè) ajax 對象中有一個(gè)成員叫做 xhr.status
- 這個(gè)成員就是記錄本次請求的 http 狀態(tài)碼的
兩個(gè)條件都滿足的時(shí)候,才是本次請求正常完成
readystatechange
- 在 ajax 對象中有一個(gè)事件,叫做 readystatechange 事件
- 這個(gè)事件是專門用來監(jiān)聽 ajax 對象的 readyState 值改變的的行為
- 也就是說只要 readyState 的值發(fā)生變化了,那么就會觸發(fā)該事件
- 所以我們就在這個(gè)事件中來監(jiān)聽 ajax 的 readyState 是不是到 4 了
xhr.open('get',?'./data.php')
xhr.send()
xhr.onreadystatechange?=?function?()?{
?//?每次?readyState?改變的時(shí)候都會觸發(fā)該事件
?//?我們就在這里判斷?readyState?的值是不是到?4
?//?并且?http?的狀態(tài)碼是不是?200?~?299
?if?(xhr.readyState?===?4?&&?/^2\d{2|$/.test(xhr.status))?{
?//?這里表示驗(yàn)證通過
?//?我們就可以獲取服務(wù)端給我們響應(yīng)的內(nèi)容了
??}
}
responseText
- ajax 對象中的 responseText 成員
- 就是用來記錄服務(wù)端給我們的響應(yīng)體內(nèi)容的
- 所以我們就用這個(gè)成員來獲取響應(yīng)體內(nèi)容就可以
xhr.open('get',?'https://api.github.com/users/sunshineyanghui')
xhr.send()
xhr.onreadystatechange?=?function?()?{
??if?(xhr.readyState?==?4?&&?/^2\d{2|$/.test(xhr.status))?{
????//?我們在這里直接打印?xhr.responseText?來查看服務(wù)端給我們返回的內(nèi)容
????console.log(xhr.responseText)
??}
}
截圖:
使用 ajax 發(fā)送請求時(shí)攜帶參數(shù)
- 我們使用 ajax 發(fā)送請求也是可以攜帶參數(shù)的
- 參數(shù)就是和后臺交互的時(shí)候給他的一些信息
- 但是攜帶參數(shù) get 和 post 兩個(gè)方式還是有區(qū)別的
發(fā)送一個(gè)帶有參數(shù)的 get 請求
- get 請求的參數(shù)就直接在 url 后面進(jìn)行拼接就可以
//?直接在地址后面加一個(gè)??,然后以?key=value?的形式傳遞
//?兩個(gè)數(shù)據(jù)之間以?&?分割
xhr.open('get',?'./data.php?a=100&b=200')
xhr.send()
- 這樣服務(wù)端就能接受到兩個(gè)參數(shù)
- 一個(gè)是 a,值是 100
- 一個(gè)是 b,值是 200
發(fā)送一個(gè)帶有參數(shù)的 post 請求
- post 請求的參數(shù)是攜帶在請求體中的,所以不需要再 url 后面拼接
xhr.open('post',?'./data.php')
//?如果是用?ajax?對象發(fā)送?post?請求,必須要先設(shè)置一下請求頭中的?content-type
//?告訴一下服務(wù)端我給你的是一個(gè)什么樣子的數(shù)據(jù)格式
xhr.setRequestHeader('content-type',?'application/x-www-form-urlencoded')
//?請求體直接再 send 的時(shí)候?qū)懺?()?里面就行
//?不需要問號,直接就是?'key=value&key=value'?的形式
xhr.send('a=100&b=200')
- application/x-www-form-urlencoded 表示的數(shù)據(jù)格式就是 key=value&key=value
封裝 AJAX
- ajax 使用起來太麻煩,因?yàn)槊看味家獙懞芏嗟拇a
- 那么我們就封裝一個(gè) ajax 方法來讓我們使用起來簡單一些
因?yàn)橛幸恍﹥?nèi)容可以不傳遞,我們可以使用默認(rèn)值,所以選擇對象傳遞參數(shù)的方式 // 使用的時(shí)候直接調(diào)用,傳遞一個(gè)對象就可以
ajax({??url:?'',?//?請求的地址
??type:?'',?//?請求方式
??async:?'',?//?是否異步
??data:?'',?//?攜帶的參數(shù)
??dataType:?'',?//?要不要執(zhí)行?json.parse
??success:?function?()?{}?//?成功以后執(zhí)行的函數(shù)
})
確定好使用方式以后,就開始書寫封裝函數(shù)
封裝
function?ajax(options)?{??//?先準(zhǔn)備一個(gè)默認(rèn)值
??var?defInfo?=?{
????url:?'',?//?地址不需要默認(rèn)值
????type:?'GET',?//?請求方式的默認(rèn)值是?GET
????async:?false,?//?默認(rèn)值是異步
????data:?'',?//?參數(shù)沒有默認(rèn)值
????dataType:?'string',?//?默認(rèn)不需要執(zhí)行?json.parse
????success?()?{},?//?默認(rèn)是一個(gè)函數(shù)
??}
??//?先來判斷一下有沒有傳遞?url,如果沒有,直接拋出異常
??if?(!options.url)?{
????throw?new?Error('url?必須傳遞')
??}
??//?有了?url?以后就,我們就把用戶傳遞的參數(shù)和我們的默認(rèn)數(shù)據(jù)合并
??for?(let?key?in?options)?{
????defInfo[key]?=?options[key]
??}
??//?接下來的一切我們都是使用我們的?defInfo?就可以了
??//?第一步就是判斷參數(shù)?data
??//?data?可以不傳遞,可以為空
??//?data?也可以是一個(gè)?key=value&key=value?格式的字符串
??//?data?也可以是一個(gè)對象
??//?否則就拋出異常
??if?(!(typeof?defInfo.data?===?'string'?&&?/^(\w+=\w+&?)*$/.test(defInfo.data)?||?Object.prototype.toString.call(defInfo.data)?===?'[object?Object]'))?{
????throw?new?Error('請按照要求傳遞參數(shù)')
??}
??//?參數(shù)處理完畢以后,在判斷?async?的數(shù)據(jù)類型
??//?只能傳遞?布爾數(shù)據(jù)類型
??if?(typeof?defInfo.async?!==?'boolean')?{
????throw?new?Error('async?參數(shù)只接受布爾數(shù)據(jù)類型')
??}
??//?在接下來就判斷?type
??//?請求方式我們只接受 GET 或著 POST
??if?(!(defInfo.type.toUpperCase()?===?'GET'?||?defInfo.type.toUpperCase()?===?'POST'))?{
????throw?new?Error('目前本插件只接受?GET?和?POST?方式,請期待更新')
??}
??//?接下來就是判斷?success?的判斷,必須是一個(gè)函數(shù)
??if?(Object.prototype.toString.call(defInfo.success)?!==?'[object?Function]')?{
????throw?new?Error('success?只接受函數(shù)數(shù)據(jù)類型')
??}
??//?參數(shù)都沒有問題了
??//?我們就要把?data?處理一下了
??//?因?yàn)?data?有可能是對象,當(dāng)?data?是一個(gè)對象的時(shí)候,我們要把它轉(zhuǎn)換成一個(gè)字符串
??var?str?=?''
??if?(Object.prototype.toString.call(defInfo.data)?===?'[object?Object]')?{
????for?(let?attr?in?defInfo.data)?{
??????str?+=?`${attr}=${defInfo.data[attr]}&`
????}
????str?=?str.slice(0,?-1)
????defInfo.data?=?str
??}
??//?參數(shù)全部驗(yàn)證過了以后,我們就可以開始進(jìn)行正常的?ajax?請求了
??//?1.?準(zhǔn)備一個(gè)?ajax?對象
??//????因?yàn)橐幚砑嫒輪栴},所以我們準(zhǔn)備一個(gè)函數(shù)
??function?createXHR()?{
????if?(XMLHttpRequest)?{
??????return?new?XMLHttpRequest()
????}?else?{
??????return?new?ActiveXObject('Microsoft.XMLHTTP')
????}
??}
??//?2.?創(chuàng)建一個(gè)?ajax?對象
??var?xhr?=?createXHR()
??//?3.?進(jìn)行?open
??xhr.open(defInfo.type,?defInfo.url?+?(defInfo.type.toUpperCase()?===?'GET'???`?${defInfo.data}&_=${new?Date().getTime()}`?:?''),?defInfo.async)
??if?(defInfo.type.toUpperCase()?===?'POST')?{
????xhr.setRequestHeader('content-type',?'application/x-www-form-urlencoded')
??}
??//?4.?進(jìn)行?send
??xhr.send((defInfo.type.toUpperCase()?===?'POST'???`${defInfo.data}`?:?''))
??//?5.?接受響應(yīng)
??xhr.onreadystatechange?=?function?()?{
????if?(xhr.readyState?===?4?&&?/2\d{2}/.test(xhr.status))?{
??????//?表示成功,我們就要執(zhí)行?success
??????//?但是要進(jìn)行?dataType?的判斷
??????if?(defInfo.dataType?===?'json')?{
????????defInfo.success(JSON.parse(xhr.responseText))
??????}?else?{
????????defInfo.success()
??????}
????}
??}
}
往期推薦
值得收藏的前端必備javascript,this指向詳解~
css常用和常用卻容易忘記的樣式合集
超級實(shí)用的JavaScript調(diào)試技巧分享,跟我一起長知識吧!!
你點(diǎn)的每一個(gè)在看,我都認(rèn)真當(dāng)成了喜歡
總結(jié)
以上是生活随笔為你收集整理的ajax datatype_小白跟我一起学习ajax的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: addeventlistener事件第三
- 下一篇: pmp知识点详解-项目大牛整理_PMP核