本文主要是我學習ajax的筆記,不涉及到原理,只是記錄如何使用。如果有錯歡迎各位大佬指出。提前先轉一篇寫的非常全面的博客你真的會使用XMLHttpRequest嗎?
一、ajax概念
1、ajax是一種技術方案,但並不是一種新技術。它依賴的是現有的CSS/HTML/Javascript,ajax依靠瀏覽器提供的XMLHttpRequest對象讓瀏覽器發出HTTP請求與接收HTTP響應,實現在頁面不刷新的情況下和服務端進行數據交互
2、依靠對象
XMLHttpRequest對象
fetch對象 (兼容性較弱)
二、採用同步的方式通過ajax獲取數據(簡單版)
1、代碼
我在當前html文件下僞造了一個hello.json的文檔,作爲服務器資源。
<script>
var xhr =new XMLHttpRequest() //生成一個新的XMLHttpRequest對象
xhr.open('GET','hello.json',false)//第一個參數是請求獲取數據的方式,第二個參數是請求服務器對應地址,參數三是false是同步獲取,true是異步獲取
xhr.send()
var data= xhr.responseText
console.log(data)
</script>
控制檯報錯,顯示用file協議是不支持的,跨源請求僅支持http, data, chrome, chrome-extension, https協議方案
所以我們打開終端gitbash,切換到html當前文件下,輸入http-server打開本地服務器
打開服務器後,返回兩個地址,125的地址是本地局域網環境的 ip,127的ip是本機 ip。
這兩個地址的區別,可以點擊這個鏈接查看
複製這個IP地址到瀏覽器上,打開對應的html文件,得到了對應的ajax數據
2、總結:
採用同步的方式,也能獲得數據,但是時間比較長,差不多22ms(個人電腦上的數據,並非實驗數據),效率不高。
把參數三把false改成true,就可以變異步。xhrsend之後立刻就執行返回數據的操作,導致沒有數據返回。
如果需要採用異步的方式獲取ajax數據,就需要綁定load事件,等加載後再執行var data= xhr.responseText,才返回數據
三、採用異步綁定事件的方式獲取ajax數據
1、代碼
異步綁定數據,需要綁定load事件
var xhr =new XMLHttpRequest()
// xhr.open('GET','hello.json',true)
// xhr.send()
// xhr.addEventListener('load',function(){
// var data= xhr.responseText
// console.log(data)
// console.log(xhr.status)
// })
四、xhr.status
1、概念
status是XMLHttpRequest對象的一個屬性,表示響應的HTTP狀態碼。
該狀態碼用於表示特定 HTTP 請求是否已成功完成,這個狀態碼是服務器發給瀏覽器的
2、status數值分類
3、所有status其餘狀態碼
這篇博客(Ajax關於readyState(狀態值)和status(狀態碼)的研究) 上寫status其餘狀態碼比較詳細
也可以查閱mdn,我這裏只是挑出幾個常用的狀態碼
3.1) 200 請求成功。成功的含義取決於HTTP方法:
- GET:資源已被提取並在消息正文中傳輸。
- HEAD:實體標頭位於消息正文中。
- POST:描述動作結果的資源在消息體中傳輸。
- TRACE:消息正文包含服務器收到的請求消息
3.2)404 Not Found
請求失敗,被廣泛應用於當服務器不想揭示到底爲何請求被拒絕或者沒有其他適合的響應可用的情況下。
3.3)304 Not Modified(未改變)
如果客戶端發送了一個帶條件的 GET 請求且該請求已被允許,而文檔的內容(自上次訪問以來或者根據請求的條件)並沒有改變,則服務器應當返回這個狀態碼
未改變說明無需再次傳輸請求的內容,也就是說可以使用緩存的內容。
4、舉個例子
var xhr= new XMLHttpRequest()
xhr.timeout=13
// 注意timeout時間要根據收到json文件響應時間來設置,小於這個時間會輸出timeout
xhr.open('GET','hello.json',true)
xhr.send()
xhr.addEventListener('load',function(){
console.log(xhr.status)
if((xhr.status>=200 && xhr.status<300)||xhr.status==304){
console.log(this.responseText)
}else{
console.log('fail')
}
})
xhr.ontimeout=function(e){
console.log('timeout')
}
xhr.onerror=function(){
console.log('error')//一般是連接失敗報錯
}
坑1:onerror和status中的錯誤狀態的區別
onerror是定義一個事件,當ajax連接失敗(瀏覽器發送ajax請求根本沒有連接到服務器)瀏覽器自己輸出error。status是請求鏈接到服務器,服務器響應錯誤後服務器返回瀏覽器的狀態碼。詳情可以查看這個鏈接
坑2:XMLHttpRequest提供了timeout的屬性,爲了防止請求過了很久還沒有成功,白白佔用的網絡資源。timeout是指響應時間,開始請求到接收到響應(開始處理)的時間,單位爲ms。
比如我設置timeout時間爲5ms
結果請求超時,返回的是timeout
timeout對應console臺,應該是以下紅框的總時間。
五、readystate
1、概念
XMLHttpRequest 的一個屬性,用來表示當前XMLHttpRequest對象處於什麼狀態
有5個值,mdn的解析
0 | 初始化,XMLHttpRequest對象還沒有完成初始化(但尚未調用 open() 方法) |
---|---|
1 | 載入,XMLHttpRequest對象開始發送請求 |
2 | 載入完成,XMLHttpRequest對象的請求發送完成 |
3 | 下載解析中,XMLHttpRequest對象開始讀取服務器的響應 |
4 | 完成,XMLHttpRequest對象讀取服務器響應結束 |
2、舉個例子
var xhr= new XMLHttpRequest()
xhr.open('GET','hello.json',true)
xhr.send()
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
// redyState的s一定要大寫,不然不輸出,但綁定事件的onreadystatechange是小寫
if((xhr.status>=200 && xhr.status<300 ) ||xhr.status==304){
console.log(xhr.responseText)
}else{
console.log('fail')
}}
}
執行結果
每次readystatechange,都會觸發事件,輸出readystate
3、坑
redyState的s一定要大寫,不然不輸出,但綁定事件的onreadystatechange是小寫
六、get和post方式參數的位置
get方式會把參數拼裝成url後
post會把參數放在xhr.send()內部
var xhr = new XMLHttpRequest()
xhr.timeout = 3000 //可選,設置xhr請求的超時時間
xhr.open('POST', '/register', true)
xhr.onload = function(e) {
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
console.log(this.responseText)
}
}
//可選
xhr.ontimeout = function(e) {
console.log('請求超時')
}
//可選
xhr.onerror = function(e) {
console.log('連接失敗')
}
//可選
xhr.upload.onprogress = function(e) {
//如果是上傳文件,可以獲取上傳進度
}
xhr.send('username=jirengu&password=123456')
七、封裝一個 ajax對象
function ajax(opts){
var url = opts.url
var type = opts.type || 'GET'
var dataType = opts.dataType || 'json'
var onsuccess = opts.onsuccess || function(){}
var onerror = opts.onerror || function(){}
var data = opts.data || {}
var dataStr = []
for(var key in data){
dataStr.push(key + '=' + data[key])
}
dataStr = dataStr.join('&')
if(type === 'GET'){
url += '?' + dataStr
}
var xhr = new XMLHttpRequest()
xhr.open(type, url, true)
xhr.onload = function(){
if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
//成功了
if(dataType === 'json'){
onsuccess( JSON.parse(xhr.responseText))
}else{
onsuccess( xhr.responseText)
}
} else {
onerror()
}
}
xhr.onerror = onerror
if(type === 'POST'){
xhr.send(dataStr)
}else{
xhr.send()
}
}
ajax({
url: 'http://api.jirengu.com/weather.php',
data: {
city: '北京'
},
onsuccess: function(ret){
console.log(ret)
},
onerror: function(){
console.log('服務器異常')
}
})