最近在學(xué)習(xí)Ajax相關(guān)的內(nèi)容。談到Ajax就不得不提HTTP協(xié)議,Ajax就是使用JavaScript來(lái)發(fā)送,一個(gè)HTTP請(qǐng)求,并且可以接收從服務(wù)器返回的HTTP響應(yīng)。下面我們來(lái)聊一下Ajax和HTTP協(xié)議。
HTTP 協(xié)議
HTTP的全稱是超文本傳輸協(xié)議(英文:HyperText Transfer Protocol),它是客戶端與服務(wù)器請(qǐng)求和響應(yīng)的標(biāo)準(zhǔn)。HTTP使得客戶端與服務(wù)器之間可以進(jìn)行通信,傳輸與接收數(shù)據(jù)。更詳細(xì)的定義可以查看維基百科:HTTP協(xié)議。
我們具體來(lái)看一下,HTTP的請(qǐng)求與響應(yīng)。
HTTP 請(qǐng)求
HTTP請(qǐng)求分為四部分,格式如下所示:
1 請(qǐng)求的動(dòng)詞 路徑 協(xié)議/版本
2 key1: value1
2 key2: value2
2 key3: value3
2 ...
2 Content-Type: value
2 Host: www.baidu.com
2 User-Agent: curl/7.57.0
3 (回車)
4 要上傳的數(shù)據(jù)
對(duì)于第一部分,第三部分,第四部分都好理解,第二部分需要說(shuō)明一下。第二部分是請(qǐng)求的頭信息,用來(lái)描述一些元數(shù)據(jù),服務(wù)器會(huì)根據(jù)頭信息,作出相應(yīng)的處理方式。
HTTP 響應(yīng)
HTTP響應(yīng)也有四部分,格式如下:
1 協(xié)議/版本號(hào) 狀態(tài)碼 狀態(tài)解釋
2 key1: value1
2 key2: value2
2 Content-Length: 2443
2 Content-Type: text/html
2 ...
3 (回車)
4 要下載的內(nèi)容
響應(yīng)部分也是一樣,第一,第三部分不用多解釋,第二部分返回響應(yīng)頭信息,客戶端根據(jù)頭信息,作出相應(yīng)的處理操作。第四部分是請(qǐng)求體,即:服務(wù)器根據(jù)請(qǐng)求響應(yīng)的內(nèi)容。
Ajax
Ajax的全稱是Asynchronous JavaScript and XML。在沒(méi)有Ajax之前,前端想要向請(qǐng)求后端的數(shù)據(jù),可以使用的方式有:
-
form表單請(qǐng)求 『缺點(diǎn):頁(yè)面會(huì)刷新』 -
img通過(guò) img 標(biāo)簽,向服務(wù)器發(fā)送請(qǐng)求 『缺點(diǎn):只能發(fā)送GET,頁(yè)面沒(méi)有刷新,只能請(qǐng)求圖片』 -
script標(biāo)簽請(qǐng)求,傳遞回調(diào)函數(shù)給后臺(tái),后臺(tái)把數(shù)據(jù)放入回調(diào)函數(shù)中,當(dāng)作參數(shù),執(zhí)行?!喝秉c(diǎn):只能發(fā)送GET請(qǐng)求』(這就是jsonp) - ...
以上這些方式要么需要刷新頁(yè)面,要么只能發(fā)送get請(qǐng)求。做不到既可以發(fā)送除GET以外的請(qǐng)求,并且不刷新頁(yè)面的效果。而Ajax就是為了解決這么一個(gè)問(wèn)題出現(xiàn)的,說(shuō)白了Ajax就是讓JavaScript可以發(fā)送HTTP請(qǐng)求和接收HTTP響應(yīng)。
Ajax 的歷史
1999年微軟就在IE5.0上就引入了可以讓JavaScript發(fā)送請(qǐng)求的接口,但是一開始并沒(méi)有引起重視,直到2004年Gmail的發(fā)布,才引起廣泛的關(guān)注。在2005年Ajax這個(gè)詞被提出。后來(lái)Ajax這個(gè)詞就成為了JavaScript腳本發(fā)起HTTP通信的代名詞。
Ajax 的使用
Ajax一般包括以下步驟
- 創(chuàng)建
XMLHttpRequest實(shí)例- 發(fā)出
HTTP請(qǐng)求- 接收服務(wù)器傳回的數(shù)據(jù)
- 處理網(wǎng)頁(yè)數(shù)據(jù)
Ajax 請(qǐng)求 前端代碼
以下是一個(gè)簡(jiǎn)單的Ajax的示例:
let xhr = new XMLHttpRequest();
xhr.open('GET','http://jack.com/ajax');
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencode;charset=utf-8');
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
let string = xhr.responseText;
let obj = JSON.parse(string);
console.log('請(qǐng)求成功');
} else if(xhr.status >= 400){
console.log('請(qǐng)求失敗');
}
}
}
xhr.send('a=9&b=6');
上述代碼與HTTP請(qǐng)求方式相對(duì)應(yīng)
-
xhr.open()對(duì)應(yīng)了HTTP請(qǐng)求的請(qǐng)求方式、請(qǐng)求路徑、請(qǐng)求的域名 -
xhr.setRequestHeader()配置 請(qǐng)求頭信息 -
xhr.onreadystatechange()當(dāng)狀態(tài)發(fā)生改變時(shí),判斷當(dāng)前的請(qǐng)求狀態(tài)以及響應(yīng)的狀態(tài)。定義成功與失敗的回調(diào)函數(shù)。 -
xhr.send()請(qǐng)求的數(shù)據(jù)
Ajax 響應(yīng) node.js后端代碼
以下是一個(gè)簡(jiǎn)單的node.js服務(wù)端處理HTTP響應(yīng)的示例:
if(pathNoQuery === '/ajax'){
response.statusCode = 200;
response.setHeader('Access-Control-Allow-Origin','http://testa.com:8890'); //設(shè)置允許跨域請(qǐng)求的 源
response.setHeader('Content-Type','application/json'); //設(shè)置返回的數(shù)據(jù)形式是 JSON
response.write(`{"name":"miralce","method":"ajax"}`);
response.end();
}
上述代碼跟HTTP的響應(yīng)方式相對(duì)應(yīng)
-
response.statusCode設(shè)置狀態(tài)碼,告知請(qǐng)求的狀態(tài),成功與否 -
response.setHeader設(shè)置響應(yīng)的響應(yīng)頭信息 -
response.write設(shè)置響應(yīng)體數(shù)據(jù),返回給前端的數(shù)據(jù) -
response.end()響應(yīng)結(jié)束發(fā)送
Ajax 的封裝
一般來(lái)說(shuō)直接寫Ajax代碼比較多,不利于書寫,所以可能需要對(duì)Ajax進(jìn)行封裝,利用jQuer的思路,在結(jié)合ES6的Promise:
window.jQuery.ajax = function({url,method,header,body}){
return new Promise(function(resolve,reject){
let xhr = new XMLHttpRequest();
xhr.open(method,url);
for(let key in header){
xhr.setRequestHeader(key,header[key]);
}
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
resolve(xhr.responseText);
}else{
reject(xhr);
}
}
}
let bodys = '';
for(let key in body){
bodys += `${key}=${body[key]}`;
}
xhr.send(bodys);
})
}
調(diào)用的方式
$.ajax({
url: '/ajax',
method: 'post',
header: {
'Content-Type': 'application/x-www-form-urlencode;charset=utf-8',
'user': 'miracle'
},
body: {
'name': 'miracle',
'time': Date.now()
}
}).then(resText=>{
let res = JSON.parse(resText);
console.log(res);
},xhr=>{
console.log(xhr);
})
總結(jié)
Ajax技術(shù)是前端的一個(gè)里程碑,它的出現(xiàn)直接改變了人們對(duì)前端的認(rèn)識(shí),對(duì)前端的發(fā)展有著巨大的推動(dòng)作用。也是現(xiàn)在的前端開發(fā)人員不得不掌握的技能之一。
以上只是本人對(duì)Ajax和HTTP簡(jiǎn)單的看法,若有寫的不正確或者不好的地方,歡迎指正。
本文僅供學(xué)習(xí)與交流使用,轉(zhuǎn)載請(qǐng)注明出處。