Ajax
- 即Asynchronous Javascript And XML(異步JavaScript和XML),
- 是一種js常用與異步通信的技術(shù)。也是指一種創(chuàng)建交互式網(wǎng)頁應(yīng)用的網(wǎng)頁開發(fā)技術(shù)。(也可以做同步通信,對講機)
異步通信,依賴服務(wù)器,發(fā)請求出去,前端不受通信流程影響
同步異步
- 同步:指的是事件按先后順序依次進行,步驟之間存在依賴關(guān)系,不能顛倒,如,買菜,洗菜,切菜,燒菜
- 異步:典型場景:燒水,聽歌,玩手機,事件彼此 之間可以同時進行,事件并不被其他事件干擾或等待,事件之間不管誰先結(jié)束,燒水,看報紙,喝茶
- 通信步驟
- 準備信紙————創(chuàng)建通信對象
var xhr = new XMLHttpRequest();
- 在早期IE版本中,使用ActiveXObject創(chuàng)建對象
- 寫信————通信初始化
xhr.open("get","data.json",true);
- 送信發(fā)信————發(fā)送
xhr.send();
- 收到回信————監(jiān)聽
xhr.onreadystatechange =function(){
if(readyState ==4){
console.log(xhr.responseText);
}
}
- 讀信————取值
異步通信,依賴服務(wù)器,發(fā)請求出去,前端不受通信流程影響
ajax的詳細通信步驟,ajax通信,大量的通用方法
- 創(chuàng)建通信對象 使用XMLHttpRequest實例,通常變量都用xhr名字
var xhr = new XMLHttpRequest(); //new+構(gòu)造函數(shù)創(chuàng)建對象
- 初始化通信對象(發(fā)到哪里,怎么發(fā),發(fā)給誰),使用open函數(shù),open接收三個參數(shù),第一個是通信類型get/post,第二個參數(shù)url請求地址,第三個參數(shù),同步或異步,默認為true,表示異步。
xhr.open("get","data.json",true);
- 發(fā)送請求,使用send函數(shù),從這里開始,表現(xiàn)異步,等下面的監(jiān)聽完成后,send才結(jié)束,會返回2
xhr.send();
console.log(111);
xhr.onreadystatechange = function(){
//拿到數(shù)據(jù)
if(xhr.readyState ==4){
if(xhr.readyState ==4 || xhr.readyState ==3){
console.log(xhr.responseText);
}
}
- 3的狀態(tài)時,數(shù)據(jù)不大,一次接收到了,可能拿出來,可能數(shù)據(jù)未接收完整
- 4的狀態(tài)一定能拿出數(shù)據(jù)
- ajax請求數(shù)據(jù)通常放在xhr對象的responseText字段中
- 使用onreadystatechange監(jiān)聽xhr對象readyState(注意大寫)屬性值0-4 ,標識整個通信過程,接收到變成3,接收完畢變成4
ajax核心通信步驟分為五部,我們可以通過跟蹤通信對象readyState屬性來判斷通信狀態(tài)和進度
- 0到1是同步
readyState屬性 記錄當前通信進行到什么步驟,其狀態(tài)值為0-4
- 0:當通信對象創(chuàng)建完畢未初始化
- 1:當使用open初始化通信對象后狀態(tài)為1
- 2:調(diào)用send發(fā)送請求后狀態(tài)為2
- 3:開始接收返回數(shù)據(jù) 狀態(tài)為3
- 4:表示數(shù)據(jù)接收完畢
- 注意:ajax可以同步,只不過同步:必須在open步驟前面監(jiān)聽,不然監(jiān)聽不到了
get和post的區(qū)別
- 報文:報文(message)是網(wǎng)絡(luò)中交換與傳輸?shù)臄?shù)據(jù)單位,及站點一次性要發(fā)送的數(shù)據(jù)塊。報文包含了將要發(fā)送的完整的數(shù)據(jù)信息,其長短很不一致,長度不限且可變。
- post在數(shù)據(jù)傳量上,較比get要大,可以發(fā)送M級別的數(shù)據(jù)。而get只能發(fā)送k界別
- post數(shù)據(jù)在報文內(nèi)部傳輸,較比get請求將參數(shù)拼接在url后面的方式,更安全
- get請求在處理請求時,速度會比post快,理論上快一倍
get方式傳參,參數(shù)在url后以?鍵=值&鍵=值...的方式傳遞eg:?name=violet&age=23&sex=男
- 用按鈕ajax模擬get發(fā)送請求
<form action="" method= "get">
姓名:<input type = "text" name= "name"/>
年齡:<input type = "text" name= "age"/>
性別:<input type = "text" name= "sex"/>
<input type = "submit" value= "提交"/>
<input type = "button" value= "ajax提交get"/> <!-- 用ajax傳參 -->
<input type = "button" value= "ajax提交post"/>
</form>
document.querySelector("input[type =button]").onclick = function(){
//創(chuàng)建通信對象
var url = "data.json?",
inputs = document.querySelectorAll("input[type=text]");
for(var n= 0;n < inputs.length;n++){
url +=inputs[n].name+"="+inputs[n].value+"&";
}
//截取多余&
url = url.substr(0,url.length-1); //截掉最后一個多余的&
var xhr = new XMLHttpRequest();
//初始化通信對象
xhr.open("get",url,true);
//發(fā)送請求
xhr.send();
//輸出返回值
xhr.onreadystatechange = function(){
console.log(xhr.responesText);
}
};
而post請求參數(shù)放在報文內(nèi)部傳遞,ajax請求中post類型傳參,將參數(shù)放在send函數(shù)實參形式傳遞
document.querySelectorAll("input[type =button]")[1].onclick = function(){
//創(chuàng)建通信對象
var url = "data.json",
reqDate = {}, //上送空對象
inputs = document.querySelectorAll("input[type=text]");
for(var n= 0;n < inputs.length;n++){
reqDate[inputs[n].name]=inputs[n].value;
}
var xhr = new XMLHttpRequest();
//初始化通信對象
xhr.open("post",url,true);
//發(fā)送請求 post傳參 參數(shù)會被轉(zhuǎn)換為string上送給后臺
xhr.send(JSON.stringify(reqDate));
//輸出返回值
xhr.onreadystatechange = function(){
if(xhr.readyState ==4){
var data = JSON.parse(xhr.responseText);
console.log("我叫"+data.name+"我今年"+data.age);
}
};
};
JSON 對象的使用,最主流的數(shù)據(jù)傳輸方式,就是JSON,多語言數(shù)據(jù)結(jié)構(gòu)
- json格式字符串:通用的輕量級數(shù)據(jù)格式,解析比xml更快(輕量級)
- 四種通用格式:{"鍵":值} || [值,值] ||
{"鍵":[值,值]} || [{"鍵":值,"鍵":值}] - JSON.parse();將標準的JSON字符串轉(zhuǎn)換成對象,必須內(nèi)層加上雙引號,外層用單引號
console.log(JSON.parse('{"name":"tom","age":28}')); //輸出對象
- JSON.stringify()將js對象轉(zhuǎn)換成JSON字符串
console.log(JSON.stringify({"name":"tom","age":28})); //輸出字符串{"name":"tom","age":28}
- 一個對象轉(zhuǎn)化成字符串長度是15
- .json文件中不能加注釋,否則報語法錯誤
- encodeURIComponent(轉(zhuǎn)碼) 和 decodeURIComponent(變成中文)
- utf-8,數(shù)字表示用幾位來表示中文,4位都不支持中文
- utf-16,數(shù)字表示用16位表示一個字符
ajax封裝
- ajax請求函數(shù)
- @param:type 請求方式
- @param:url 請求地址
- @param:isAnsy 是否異步
- @param:sendData 上送數(shù)據(jù) {key:value}
- @param:callback 返回數(shù)據(jù),它的參數(shù)就是返回值
function postReq (type, url, isAnsy,sendData,callback){
// 創(chuàng)建通訊對象
var xhr = createXHr();
// 根據(jù)請求方式處理上送數(shù)據(jù)
if(type.toLowerCase() == "get"){
// 將對象性數(shù)據(jù)轉(zhuǎn)換為queryString結(jié)構(gòu)
url += "?";
for(var n in sendData){
url += n +"=" + sendData[n] + "&";
}
// 截取末尾多余&
url = url.substr(0,url.length-1);
// 設(shè)置sendDate為空null
sendDate = null;
}else{
// 將js對象類型數(shù)據(jù)轉(zhuǎn)化為json格式的字符串
sendData = JSON.stringify(sendData);
}
// 初始化通信對象
xhr.open(type,url,isAnsy);
// 發(fā)送請求
xhr.send(sendData);
// 監(jiān)聽請求返回狀態(tài)
xhr.onreadystatechange = function(){
// xhr對象status屬性用于描述http通信狀態(tài) statusText 是對status的描述信息
if(xhr.status == 200 || xhr.status == 304 || (xhr.status>200 && xhr.status<300)){
// console.log(xhr);
if(xhr.readyState == 4){
var resData = JSON.parse(xhr.responseText);
callback && callback(resData);
}
}
}
}
try{
console.log(abc); //可能出現(xiàn)異常的代碼
}catch(e){
console.log(e); //異常事件處理 //異常出現(xiàn)時執(zhí)行的代碼
}finally{
console.log(33); //無論是都會出現(xiàn)異常都要執(zhí)行的代碼
}
console.log("aaaa"); //無論try中是否出現(xiàn)異常都不會影響后續(xù)代碼執(zhí)行
// 創(chuàng)建一個兼容的xhr創(chuàng)建函數(shù)
function createXHr(){
絕大部分瀏覽器支持XMLHttpRequest
if (typeof XMLHttpRequest == "function"){
return new new XMLHttpRequest();
}else{
var strList = ["MSXML.XMLHttp.6.0","MSXML.XMLHttp.3.0","MSXML.XMLHttp", "Microsoft.XMLHTTP" //ie6];
// 循環(huán)嘗試創(chuàng)建xhr對象
for(var n = 0; n < strList.length; n++){
// 使用try catch 防止錯誤參數(shù)
try{
var xhr = new ActiveXObject(strList[n]);
// 返回xhr對象
return xhr;
}catch(e){
console.log(e);
}
}
}
}
html加載自上向下,自外向內(nèi)優(yōu)先級比自上向下高,
加載就是標簽節(jié)點,并不是
ajax的數(shù)據(jù)返回,如果要用數(shù)據(jù)有兩種方法:
第一種:直接將所有的東西放到請求數(shù)據(jù)函數(shù)里面
第二種:聲明全局變量,比如班級全局變量,數(shù)據(jù)全局變量,在請求函數(shù)里面賦值