Ajax設置請求和接收響應、自己封裝簡易jQuery.Ajax
這篇文章是承接前幾篇博客的,是前幾篇繼續學習 包括Ajax學習與理解和簡化版自己實現jQuery等 這篇文章只算是我的個人學習筆記,內容沒有精心排版,一些錯誤請見諒.
所有代碼都在這裏,從歷史commit可以看到所有代碼,擺闊一個簡易的node.js服務器 所有代碼在歷史commit裏(AjaxStudy---github)
1JS設置任意請求
一個http請求分爲四個部分 請求行,請求頭,回車,請求體
設置請求的四個部分(第三部分爲回車):
- 第一部分
request.open('get', '/xxx')
- 第二部分
request.setRequestHeader('content-type','x-www-form-urlencoded')
- 第四部分
request.send('a=1&b=2')
request.setRequestHeader()
方法需要注意的是此方法必須在 open()
方法和 send()
之間調用。
XMLHttpRequest.setRequestHeader()
另外需要注意的是,如果設置西請求方法爲get 並且設置了請求體(第四部分),在谷歌瀏覽器中看不到請求體,不報錯但是不顯示 示例代碼:
myButton.addEventListener("click",(e)=>{ let request = new XMLHttpRequest(); request.open('POST','/xxx')//配置request //設置第二部分 request.setRequestHeader("mataotao","123123xxx") request.setRequestHeader('content-type','x-www-form-urlencoded') request.send("a=1&b=2");//發送請求 request.onreadystatechange = ()=>{ if(request.readyState ===4){ console.log("請求和響應都完畢了"); if ( request.status>=200&&request.status<=400){ console.log('說明請求成功'); let string = request.responseText; //把符合json語法的字符串轉化爲js對應的值 let object2 = window.JSON.parse(string); console.log(object2) }else if(request.status>=400){ console.log("響應失敗"); } } } })
查看請求
2JS獲取任意響應
響應的四個部分
獲取四個部分的響應
- 第一部分
request.status
/request.statusText
- 第二部分
request.getResponseHeader()
/request.getAllResponseHeaders()
- 第四部分
request.responseText
myButton.addEventListener("click",(e)=>{ let request = new XMLHttpRequest(); request.open('POST','/xxx')//配置request //設置第二部分 request.setRequestHeader("mataotao","123123xxx") request.setRequestHeader('content-type','x-www-form-urlencoded') request.send("a=1&b=2");//發送請求 request.onreadystatechange = ()=>{ if(request.readyState ===4){ console.log("請求和響應都完畢了"); if ( request.status>=200&&request.status<=400){ console.log('說明請求成功'); //*核心代碼 */ //第一部分: console.log("獲取響應第一部分:") console.log(request.status)//200 console.log(request.statusText)//ok //第二部分: console.log("獲取響應第二部分:") console.log(request.getResponseHeader('Content-Type')) console.log(request.getAllResponseHeaders()) //第四部分: console.log("獲取響應第四部分:") console.log(request.responseText) //*核心代碼 */ let string = request.responseText; //把符合json語法的字符串轉化爲js對應的值 let object2 = window.JSON.parse(string); // console.log(object2) }else if(request.status>=400){ console.log("響應失敗"); } } } })
3 客戶端/服務器模型
客戶端使用js設置請求的四個部分, 服務器用nodejs也可以設置響應的四個部分
爲什麼要三次握手?
三次握手: A:我能連你了嗎? B: 可以連我,你連吧 A:那我連你了 開始發送數據
原因:因爲要保證A/B 都可以收發信息 ,數據才能在AB之間傳輸
1. A:我能連你了嗎? B: 可以 說明A可以發信息,B可以接受信息
2. B: 可以連我,你連吧 A:那我連你了 說明B可以發送信息,A可以接受信息
3 自己封裝jQuery.Ajax(簡單原理)
所有代碼在歷史commit裏(AjaxStudy---github)
3.1 方法一
window.jQuery = ()=>{//假裝有一個簡易的jQuery,具體封裝 let object1 = {}; boject1.addClass = function(){}; boject1.show = function(){}; return object1; } window.jQuery.ajax = (method,path,body,successFn,failFn)=>{ let request = new XMLHttpRequest(); request.open(method,path) request.send(body); request.onreadystatechange = ()=>{ if(request.readyState ===4){ if ( request.status>=200&&request.status<=400){ successFn.call(undefined,request.responseText)//執行成功函數 }else if(request.status>=400){ failFn.call(undefined,request)//執行失敗函數 } } } } window.$ = window.jQuery; myButton.addEventListener("click",(e)=>{ //使用ajax $.ajax("post", "/xxx", "username=mtt&password=1", function(result){ console.log('成功了,返回的響應體爲:') console.log(result);//打印request.responseText }, function(result){ console.log(result); console.log(result.status);//打印失敗的狀態碼 console.log(result.responseText);//打印失敗時返回的響應體 } ) })
結果: 成功時:
失敗時:(假如請求一個不存在的路徑,響應狀態碼是404,但是也有響應體responseText)
例如,訪問一個不存在的路徑/frank:
myButton.addEventListener("click",(e)=>{ //使用ajax $.ajax("post", "/frank", "username=mtt&password=1", function(result){ console.log('成功了,返回的響應體爲:') console.log(result);//打印request.responseText }, function(result){ console.log(result); console.log(result.status);//打印失敗的狀態碼 console.log(result.responseText);//打印失敗時返回的響應體 } ) })
返回狀態碼404,而且有設置的返回體
因爲我的服務器端的代碼爲:
else { response.statusCode = 404 response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(`{ "error":"404error" }`) response.end() }
這種方法的缺點:這個函數必須按照規定的順序傳參,第二,如果沒有參數就會出現類似於$.ajax("post",null,successFn,null)
的情況,必須傳有結構的參數(對象)
3.2什麼是回調
在上面的代碼中,在ajax
函數中傳了一個successFN
,failFn
函數作爲參數,但是執行的時候是在別的地方執行的(在request.onreadystatechange
裏)
if(request.readyState ===4){ if ( request.status>=200&&request.status<=400){ successFn.call(undefined,request.responseText)//執行成功函數 }else if(request.status>=400){ failFn.call(undefined,request)//執行失敗函數
這兩個函數就是回調函數
回調(callback): 回來執行的意思,自己不call. 把這個函數給別人,自己不執行,讓別人執行,就是callback
回調:使用方代碼不執行,只傳一個函數,回來再執行
回調就是傳一個函數,自己不執行,傳到別的地方讓他在那裏執行的函數!只要滿足這個條件就叫回調而已.他是一個函數,只不過在別的地方執行了
所以看上去沒有執行,實際上success了就執行傳進去的這個函數
3.3封裝方法二:傳有結構的參數(對象)
let myButton = document.getElementById('myButton'); window.jQuery = ()=>{//假裝有一個簡易的jQuery let object1 = {}; boject1.addClass = function(){}; boject1.show = function(){}; return object1; } window.jQuery.ajax = (options)=>{ //獲取傳進來的對象的value let method = options.method; let path = options.path; let body = options.body; let successFn = options.successFn; let failFn = options.failFn; let headers = options.headers; let request = new XMLHttpRequest(); request.open(method,path);//配置 for (const key in headers) {//遍歷header,設置響應頭 let value = headers[key]; request.setRequestHeader(key,value); } request.send(body);//發送,並配置響應體 request.onreadystatechange = ()=>{ if(request.readyState ===4){ if ( request.status>=200&&request.status<=400){ successFn.call(undefined,request.responseText);//執行成功函數 }else if(request.status>=400){ failFn.call(undefined,request);//執行失敗函數 } } } } window.$ = window.jQuery; myButton.addEventListener("click",(e)=>{ //使用ajax $.ajax({ method:"post", path:"/xxx", body:"username=mtt&password=1", headers:{ "content-type":'application/x-www-form-urlencoded', "mataotao":18 }, successFn:function(result){//成功函數的回調 console.log('成功了,返回的響應體爲:'); console.log(result);//打印request.responseTex }, failFn:function(){ console.log(result); console.log(result.status);//打印失敗的狀態碼 console.log(result.responseText);//打印失敗時返回的響應體 } } ) })
結果:
4真正的jQuery.ajax()API如何使用
$.ajax({ type: "GET", url: "/test", dataType: "script", data:{} success:function(){}, });
dataType
就是setRequestHeader("content-type","application/javascript")
data
就是請求的第四部分
5函數傳不同的參數
例如文檔裏的
jQuery.ajax( url [, settings ] )
jQuery.ajax( [settings ] )
jQuery.ajax
第一個參數既可以是url字符串你也可以是對象
如何實現這種封裝?
只要在最開始判斷參數長度即可
let url; if(arguments.length===1){//參數長度爲1 url = options.url; }else if(arguments.length===2){//參數長度爲2 url = arguments[0]; options = arguments[1]; }
其餘代碼不變
6 一點點ES6語法:解構賦值
或者直接