1. 今天的內容其實挺多的,我們慢慢來說。首先第一個是xhr的基本使用,什麼是xhr? XMLHTTPRequest是瀏覽器提供的js對象,可以請求伺服器上的數據資源,包括我們前面一直用的jq裡面的三個請求資源的方法都是基於xhr來封裝的。 那麼首先我們看到xhr的get請求怎麼來實現 首先要創建x ...
1.
今天的內容其實挺多的,我們慢慢來說。首先第一個是xhr的基本使用,什麼是xhr?
XMLHTTPRequest是瀏覽器提供的js對象,可以請求伺服器上的數據資源,包括我們前面一直用的jq裡面的三個請求資源的方法都是基於xhr來封裝的。
那麼首先我們看到xhr的get請求怎麼來實現
首先要創建xhr實例通過new來實現
然後調用open函數,裡面值為請求方式以及url
第三步調用send函數
第四步監聽onreadyStateChange事件在這個事件裡面要註意一下請求狀態和伺服器響應狀態的固定寫法,還有伺服器響應回的數據
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.創建xhr對象 var xhr = new XMLHttpRequest() // 2.調用open函數 決定請求方式和url xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks') // 3.調用send函數 xhr.send() // 4.監聽事件 xhr.onreadystatechange = function() { // 4.1註意請求狀態和伺服器響應狀態固定寫法 if (xhr.readyState ==4 && xhr.status == 200) { // 4.2獲取相應的數據 console.log(xhr.response); } } </script> </body> </html>0.2 1
我們看到在監聽請求狀態變化事件里有一個readystate的屬性這個屬性表示ajax當前請求所處的狀態,其中0表示xhr對象以創建,但請求未調用open。1表示已調用open函數。2表示已調用send函數。3表示數據接收中。最後4表示一切請求完成
那麼xhr帶參的get請求怎麼來實現的呢?只需要在open函數的url裡面接一個查詢字元串即可
xhr.open('get', 'http://www.ssfddaf.com/api?name=%df%fd%gf')
那麼什麼是查詢字元串?
在url末尾加上?參數=值多個參數間用&來連接這就是查詢字元串,無論是jQuery的三個請求方式還是xhr指定的參數其本質都是在url後帶查詢字元串
這裡還要瞭解一個點url編碼與解碼
url中只允許出線英文不允許中文等其他語種,所以他就會把除英文外其他語種轉換為%開頭帶兩個字元的樣式來代替
編碼encodeURI('中文;) 解碼decodeURI(%的字元)三組%表示一個中文
2.
接下來我們看到xhr怎麼發起post請求
第一步創建對象
第二部open函數把請求方式改為post
第三步設置content-type 這是一個固定寫法
xhr.setRequestHeader(‘content-type’, ‘application/x-www-form-urlencoded’)
第四步調用send函數 post的參數在這裡添加以查詢字元串的方式添加進來
第五步監聽事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.創建xhr對象 var xhr = new XMLHttpRequest() // 2.調用open函數 xhr.open('post', 'http://www.liulongbin.top:3006/api/addbook') // 3.設置cententtype xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') // 4.調用send函數 xhr.send('bookname=水府傳&author=我') // 5.監聽事件 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } } </script> </body> </html>
3.
數據交換格式
即伺服器與客戶端之間進行數據傳輸與交換的格式,XML和JSON這兩種
XML我們用的比較少,它是可擴展標記語言,跟html很相似
JSON
什麼事json,就是js對象和數組的字元串表示法,其中本質還是一個字元串它是輕量級文本數據交換格式
它的結構為有兩種對象結構和數組結構
對象結構
‘{key:value}’咋一看跟對象很相似,但是首先外面會有引號,其次鍵值是字元類型必須加雙引號
數組結構
【a,a】
要註意的是鍵值的雙引號,json中不能寫註釋,不能使用undefined和函數作為值
json和對象互轉
obj = JSON.parse(json)(反序列化)
json = JSON.stringify(obj)(序列化)
4.
封裝自己的ajax函數
①先封裝一個處理data對象為查詢字元串的函數
②封裝函數xhr
③判斷不同的請求類型達到不同的方式
這個總之記住一點就是xhr調用請求的總體步驟就沒得問題
// 1.先封裝函數處理傳進來的參數為查詢字元串 function revolveData(data) { var arr = [] for (var k in data) { arr[arr.length] = k + '=' + data[k] } var str = arr.join('&') return str } // console.log(revolveData({name : '張三', age : 19})); // 2。封裝主體函數 function ajaxMine(obj) { var xhr = new XMLHttpRequest() var str = revolveData(obj.data) xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { var res = JSON.parse(xhr.response) obj.success(res) } } // 3.判斷不同的請求,做到不同的操作 if (obj.method.toUpperCase() == 'GET') { xhr.open(obj.method, obj.url + '?' +str) xhr.send() } else if (obj.method.toUpperCase() == 'POST') { xhr.open(obj.method, obj.url) xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded') xhr.send(str) } }
驗證
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./封裝自己的ajax函數.js"></script> <script> /* ajaxMine({ method : 'get', url : 'http://www.liulongbin.top:3006/api/getbooks', data : { id : 2 }, success : function(res) { console.log(res); } }) */ ajaxMine({ method : 'post', url : 'http://www.liulongbin.top:3006/api/addbook', data : { bookname : '收首飾', author : '東風似舊', publisher : '身法' }, success : function(res) { console.log(res); } }) </script> </body> </html>
5.
xhr level2新特性
在我們舊版的xhr缺點就是不支持文件上傳而且沒有進度信息只有完沒完成
在我們新版xhr
支持文件上傳,有進度信息,還可以設置http時限,還可使用formdata對象管理表單數據
接下來我會一一開始xhr這四個新特性
5.1
首先第一個設置Http時限,也就是在規定時間如果還沒有完成請求任務那麼這個請求就失敗了
xhr.timeout = 2000
與之對應的還有一個ontimeout的事件在超時後會做些什麼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> var xhr = new XMLHttpRequest() xhr.timeout = 50 xhr.ontimeout = function() { console.log('請求超時了'); } xhr.open('get', 'http://www.liulongbin.top:3006/api/getbooks') xhr.send() xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } } </script> </body> </html>
5..2
formdata管理表單
因為我們ajax主要是用來提交表單數據的嘛,所以H5就新增了一個FormData對象用來模擬表單操作
①新建formdata對象
②為formdata添加表單項
③創建xhr
④用xhr完成請求
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script> // 1.創建FormData對象 var fd = new FormData() // 2.往裡面添加表單項 fd.append('uname', '王五') fd.append('age' , 29) // 3,創建xhr對象 var xhr = new XMLHttpRequest() // 4.使用xhr對象制定請求類型與地址 xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') // 5.直接提交,formdata對象,這與提交網頁表單的效果完全一樣 xhr.send(fd) // 6.驗證 xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responsete); } } </script> </body> </html>
formdata還有一個用法,就是可以用來獲取表單的值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form action=""> <input type="text" name="uname"> <input type="password" name="pwd"> <input type="submit" value="提交"> </form> <script> var form = document.querySelector('form') form.onsubmit = e => { e.preventDefault() var xhr = new XMLHttpRequest() var fd = new FormData(form) xhr.open('post', 'http://www.liulongbin.top:3006/api/formdata') xhr.send(fd) xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { console.log(xhr.responseText); } } } </script> </body> </html>
5.3
上傳文件
①定義UI結構
②驗證是否選擇了文件
③像formdata追加文件
④用xhr發起上傳請求
⑤監聽事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 1.定義ui結構 --> <!-- 1.1文件選擇框 --> <input type="file"> <!-- 1.2上傳按鈕 --> <input type="submit" value="上傳文件"> <!-- 1.3img標簽 用來顯示上傳成功後的圖片 --> <img src="" alt=""> <script> // 2.驗證是否上傳了文件 var uploadBtn = document.querySelector('input:nth-of-type(2)') uploadBtn.addEventListener('click', function() { // 2.1註意這裡這個。files它是一個數組存放的是文件 let files = document.querySelector('input:first-child').files if (files.length > 0) { // 3.像formdata中追加文件 var fd = new FormData() // avator為頭像假裝這裡是上傳的頭像 fd.append('avatar', files[0]) // 4.使用xhr發起上傳文件請求 var xhr = new XMLHttpRequest() xhr.open('post', 'http://www.liulongbin.top:3006/api/upload/avatar') xhr.send(fd) // 5.監聽事件 xhr.onreadystatechange = () => { if (xhr.readyState == 4 && xhr.status == 200) { // console.log(xhr.responseText); let imgData = JSON.parse(xhr.responseText)