终于明白如何去写原生AJAX
面試常問的題----手寫原生AJAX。 以下是個人的歸納總結,希望對大家有幫助。
一)原生JavaScript寫出AJAX
首先我們根據文檔進行相應的步驟分析。 第一步:創建對象 第二步:初始化 HTTP 請求參數 第三步:發送請求 第四步:監聽請求狀態,執行對應回調函數
前置知識
onreadystatechange 每次狀態改變所觸發事件的事件。
responseText 從服務器接收到的響應體(不包括頭部),或者如果還沒有接收到數據的話,就是空字符串。
responseXML 對請求的響應,解析為 XML 并作為 Document 對象返回。
status 從服務器返回的數字代碼,比如常見的404(未找到)和200(已就緒)
status Text 請求的 HTTP 的狀態代碼
readyState HTTP 請求的狀態.當一個 XMLHttpRequest 初次創建時,這個屬性的值從 0 開始,直到接收到完整的 HTTP 響應,這個值增加到 4。
0 (未初始化) 對象已建立,但是尚未初始化(尚未調用open方法)
1 (初始化) 對象已建立,尚未調用send方法
2 (發送數據) send方法已調用,但是當前的狀態及http頭未知
3 (數據傳送中) 已接收部分數據,因為響應及http頭不全,這時通過responseBody和responseText獲取部分數據會出現錯誤
4 (完成) 數據接收完畢,此時可以通過responseXml和responseText獲取完整的回應數據
記住這張圖
1、創建對象
IE5、6不兼容XMLHttpRequest,所以要使用ActiveXObject()對象,并傳入 'Microsoft.XMLHTTP',達到兼容目的。
var xhq = nullif (XMLHttpRequest) {xhq = new XMLHttpRequest() // 創建對象} else {xhq = new ActiveXObject("Microsoft.XMLHTTP") // 兼容IE5、6} 復制代碼2、初始化 HTTP 請求參數
語法: open(method, url, async, username, password) 參數說明: 必填 method 請求的類型 值包括 GET、POST 和 HEAD 必填 url 請求的路徑 需要向服務器請求的路徑 可選 async 此次請求的方式 默認為true 即為異步 可選 username 與 password 此次請求需要的身份驗證
同時該請求會將 readyState 設置為1,并把 responseText、responseXML、status 以及 statusText 參數設置為它們的默認值。
xhq.open('get', 'https://www.easy-mock.com/mock/5cf7654cf8ab93502742fb99/example/query', true) 復制代碼此處接口使用easy-mock模擬。
3、 發送此次請求
語法: send(body) 參數說明: 可選 傳遞的參數列表
xhq.send({username: '123'}) 復制代碼請求發送后, send()會把 readyState 設置為 2,并觸發 onreadystatechange 事件。
當所有的 HTTP 響應頭部已經接收,send() 或后臺線程把 readyState 設置為 3 并觸發 onreadystatechange 事件。
當響應完成,send() 或后臺線程把 readyState 設置為 4,并最后一次觸發事件。
4、監聽請求狀態,執行對應回調函數
當readyState為4時,且服務器響應為200時
xhq.onreadystatechange = function () {if ( xhq.readystate == 4 && xhq.status == 200 ) {// success 回調success(xhq.responseText)} else if (xhq.readyState == 4 && xhq.status !== 200) {// error 回調error()}} 復制代碼以函數方式合并所有內容為
function sendAjax(obj) { // get方式傳入時,將內容進行data內容進行拼接function splicStr(data) {var str = ''for (var i in data) {str = i + '=' + data[i]}return str} // 原生ajax實現 步驟分析 // 一、聲明XMLHttpRequest, 為了兼容IE5、6需要使用ActiveXObject()var xhq = nullif (XMLHttpRequest) {xhq = new XMLHttpRequest() // 創建對象} else {xhq = new ActiveXObject("Microsoft.XMLHTTP") // 兼容IE5、6} // 二、初始化HTTP請求參數, 只初始化并不會發送if (obj.method.toUpperCase() === 'GET') { // get方法xhq.open(obj.method, obj.url + '?' + splicStr(obj.data), typeof obj.async === 'boolean'? obj.async : true) // 路徑拼接// 三、發送此次請求xhq.send()}else if (obj.method.toUpperCase() === 'POST') { // post方法xhq.open(obj.method, obj.url, typeof obj.async === 'boolean'? obj.async : true)xhq.setRequestHeader("content-type","application/x-www-form-urlencoded") // 以表單提交// 三、發送此次請求xhq.send(obj.data)}//四、監聽發送xhq.onreadystatechange = function () {if ( xhq.readyState == 4 && xhq.status == 200 ) {// success 回調success(xhq.responseText)} else if (xhq.readyState == 4 && xhq.status !== 200) {// error 回調error()}} }sendAjax({url: 'your url',method: 'post',async: true,data: {username: 'xiong',pwd: '123'},success: function (data) {console.log(data)},error: function () {console.log('發生了錯誤')} }) 復制代碼以原型構造的方式合并為
function sendAjax(obj) {this.xhq = nullthis.method = obj.method || 'get'this.url = obj.urlthis.data = obj.datathis.async = typeof obj.async === 'boolean'? obj.async : truethis.success = obj.successthis.error = obj.errorthis.init() } sendAjax.prototype = {init: function () {if (XMLHttpRequest) {this.xhq = new XMLHttpRequest() // 創建對象} else {this.xhq = new ActiveXObject("Microsoft.XMLHTTP") // 兼容IE5、6}this.openReq()this.watchReq()},openReq: function () {if (this.method.toUpperCase() === 'GET') { // get方法this.xhq.open(this.method, this.url + '?' + this.splicStr(this.data), this.async) // 路徑拼接// 三、發送此次請求this.xhq.send()}else if (this.method.toUpperCase() === 'POST') { // post方法this.xhq.open(this.method, this.url, this.async)this.xhq.setRequestHeader("content-type","application/x-www-form-urlencoded") // 以表單提交// 三、發送此次請求this.xhq.send(this.data)}},watchReq: function () {var that = thisthis.xhq.onreadystatechange = function () {if ( that.xhq.readyState == 4 && that.xhq.status == 200 ) {// success 回調that.success(that.xhq.responseText)} else if (that.xhq.readyState == 4 && that.xhq.status !== 200) {// error 回調that.error()}}},splicStr: function (data) {var str = ''for (var i in data) {str = i + '=' + data[i]}return str} } new sendAjax({url: 'https://www.easy-mock.com/mock/5cf7654cf8ab93502742fb99/example/query',method: 'get',async: true,data: {username: 'xiong',pwd: '123'},success: function (data) {console.log(data)},error: function () {console.log('發生了錯誤')} }) 復制代碼案例沒有處理所有可能,但是已經夠基本使用。 熊吉祝大家學習愉快。
文章內容借鑒了W3school關于XMLHttpRequest文檔
轉載于:https://juejin.im/post/5d007134e51d45590a445b23
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的终于明白如何去写原生AJAX的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html比较难记的点
- 下一篇: Android之相对布局