探索AJAX
之前學習了JSONP可以發送請求去獲取數據,JSONP傳送門然后通過callback來異步的執行我們預先準備好的函數。
可是JSONP只能發送get請求,這是不是太單一了?需求很多的變化,對于復雜一點的需求的話,無法滿足,所以我們來試試用AJAX來實現跨域。
開工
先實現一個點擊按鈕發送一個請求,這里就需要介紹了一個WEB的API:XMLHttpRequest,MDN解釋:它為客戶端提供了在客戶端和服務器之間傳輸數據的功能。提供一個通過URL來獲取數據的簡單方式,并且不會使整個頁面刷新。
下面就用這個只是做一個簡單的實現:點擊一個按鈕,發送一個請求:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Document</title> </head> <body><button id="button">點我</button> <script>button.addEventListener('click', () => {let request = new XMLHttpRequest()request.open('get', '/xxx',) //使用open帶入url和一個請求request.setRequestHeader('Pomelo', '18')request.send() //發送請求request.onreadystatechange = () => {if(request.readyState === 4){if(request.status >= 200 && request.status < 300){let string = request.responseTextlet obj = window.JSON.parse(string)console.log(request.getAllRequestHeaders)console.log(obj)}else if(request.status >= 400){console.log('請求失敗')}}}}) </script> </body> </html> 復制代碼readystate
這樣就可以實現一個異步的get請求。onreadystatechage監聽readystate的變化,用一個函數來處理這個變化。 這里需要列舉一下readystate的數值及其含義。
| 0 | UNSENT(未打開) | open()方法還未被調用 |
| 1 | OPENED(未發送) | open()方法已經被調用 |
| 2 | HEADERS_RECEIVED(已獲取響應頭) | send()方法已經被調用,響應頭和響應狀態已經返回 |
| 3 | LOADING(正在下載響應體) | 響應體下載中;responseText中已經獲取了部分數據 |
| 4 | DONE(請求完成) | 整個請求過程已經完畢 |
目前來這個實現還不錯,但是每次調用就需要創建一個按鈕去發請求。發請求。發請求。這樣不會很麻煩嗎?我們模仿JQuery那樣試試看:
window.jquery.ajax = function(options){let url = options.urllet method = options.methodlet body = options.bodylet header = options.headerlet success = options.successFnlet fail = options.failFnlet request = new XMLHttpRequest()request.open(method, url) //在get請求下chrome 默認不顯示request的第四部分 for(let key in header){let value = header[key]request.setRequestHeader(key, value)}request.send(body)request.onreadystatechange = () => {if(request.readyState === 4){if(request.status >= 200 && request.status < 300){ let string = request.responseTextsuccess.call(undefined, string)}else if(request.status >= 400){fail.call(undefined, request)}}}} 復制代碼這樣一做,咱們就可以使用這樣的形式調用:
jquery.ajax({url: '/xxx',method: 'get',body: 'hello',header: 'Pomelo',success: successFn,fail: failFn }) 復制代碼使用ES6特性來優化
這樣還不錯,如果加上我們ES6的新特性,實現會更加優美:
window.jquery.ajax = function({url, method, body, header}){ //ES6 解構賦值return new Promise(function(resolve, reject){ //Promise的特性,不用帶入success和fail函數。let request = new XMLHttpRequest()request.open(method, url) //在get請求下chrome 默認不顯示request的第四部分 for(let key in header){let value = header[key]request.setRequestHeader('ni', 'hao')}request.onreadystatechange = () => {if(request.readyState === 4){if(request.status >= 200 && request.status < 300){let string = request.responseTextresolve.call(undefined, string)}else if(request.status >= 400){reject.call(undefined, request)}}}request.send(body) })} 復制代碼這樣就完成了優美的ajax的實現。調用如下:
jquery.ajax({url: '/xxx',method: 'post',body: 'hello everyone',header: {'Pomelo': '18','Hello': '18'}}}).then((xx) => { console.log(xx) },(xx) => { console.log(xx) }) 復制代碼這樣是不是就好看許多,簡單的就實現了一個ajax。
總結
- 上一篇: CUDA学习(九十一)
- 下一篇: springboot与thymeleaf