文章目錄
- 1. Ajax概述
- 1.1 什么是Ajax
- 1.2 Ajax的用途與優點
- 2. 封裝Ajax方法
- 2.1 Ajax請求的五個步驟
- 2.2 readyState的五種狀態詳解
- 2.3 封裝Ajax方法
- 2.4 初步封裝代碼
- 2.5 最終版代碼
1. Ajax概述
1.1 什么是Ajax
AJAX是創建互動式網頁應用的網頁開發技術的一種,
Ajax = 異步 JavaScript 和 XML 或者是 HTML(標準通用標記語言的子集),可以用于創建快速動態網頁的技術,在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術,通過在后臺與服務器進行少量資料交換,Ajax 可以使網頁實作異步更新,這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新,
傳統的網頁(不使用 Ajax)如果需要更新內容,必須多載整個網頁頁面,
1.2 Ajax的用途與優點
- 可以顯示新的HTML內容而不用向服務器重新請求整個頁面
- 能夠提交一個表單后立即顯示結果
- 用戶登錄而不用跳轉到新的頁面
- 遍歷資料庫資訊加載更多而不重繪頁面
正是因為這個技術的出現,讓web程式每次接發資料時,不用每次都遞交整個頁面的資料,大大提高了客戶端與服務器之間傳遞資料的速度和效率,
簡而言之,Ajax可使因特網應用程式更小、更快,更友好,Ajax最大的優點就是在客戶端與服務器交換資料時不用向服務器請求整個頁面,
2. 封裝Ajax方法
2.1 Ajax請求的五個步驟
- 創建一個異步物件
let xmlhttp = new XMLHttpRequest();
- 設定請求方式和請求地址
xmlhttp.open(type, url, true);
- 發送請求
xmlhttp.send();
- 監聽狀態的變化
xmlhttp.onreadystatechange = function(){
// 撰寫相關監聽狀態的代碼
}
- 處理回傳結果
if(xmlhttp.readyState === 4){
// 判斷是否請求成功
if(xmlhttp.status == 200){
// 5.處理回傳的結果
console.log("接收到服務器回傳的資料");
}else{
console.log("沒有接收到服務器回傳的資料");
}
}
2.2 readyState的五種狀態詳解
| 狀態 | 說明 |
|---|---|
| (0)未初始化 | 此階段確認XMLHttpRequest物件是否創建,并為呼叫open()方法進行未初始化作好準備,值為0表示物件已經存在,否則瀏覽器會報錯--物件不存在, |
| (1)載入 | 此階段對XMLHttpRequest物件進行初始化,即呼叫open()方法,根據引數(method,url,true)完成物件狀態的設定,并呼叫send()方法開始向服務端發送請求,值為1表示正在向服務端發送請求, |
| (2)載入完成 | 此階段接收服務器端的回應資料,但獲得的還只是服務端回應的原始資料,并不能直接在客戶端使用,值為2表示已經接收完全部回應資料,并為下一階段對資料決議作好準備, |
| (3)互動 | 此階段決議接收到的服務器端回應資料,即根據服務器端回應頭部回傳的MIME型別把資料轉換成能通過responseBody、responseText或responseXML屬性存取的格式,為在客戶端呼叫作好準備,狀態3表示正在決議資料, |
| (4)完成 | 此階段確認全部資料都已經決議為客戶端可用的格式,決議已經完成,值為4表示資料決議完畢,可以通過XMLHttpRequest物件的相應屬性取得資料, |
所有在監聽狀態欄改變時,只需要當 readyState == 4 時才表示已經完成了,這時再對狀態碼(status)進行檢測,通過百度可以看出,當狀態碼等于200的時候,表示服務器已經成功處理了請求,我們可以通過這一點來判斷服務器是否回傳成功,下面來封裝一個自己的Ajax方法,
2.3 封裝Ajax方法
在前面我們已經了解了 Ajax 請求的5個步驟,我們可以根據這五個步驟來封裝Ajax方法,
首先要確定是傳遞哪些引數:
| 引數 | 解釋 |
|---|---|
| url | 服務器的地址 |
| data | 傳向服務器的資料 |
| success | 當請求成功后執行的方法 |
| error | 當請求失敗后執行的方法 |
| timeout | 超時時間 |
初步考慮要解決的問題:
- 首先傳入的資料是一個物件,而客戶服務器之間的資料格式是 **key=value&key=value;**這樣的字串,所以我們首先要將傳入的物件轉換成 **key=value;**的格式
- 在url中不能出現中文,如果出現了中文是需要轉碼的
- 兼容性問題,在較低的ie瀏覽器版本是沒有XMLHttpRequest這個物件的
2.4 初步封裝代碼
function objToStr(obj) {
obj = obj || {};
for(var key in obj){
// 在URL中是不可以出現中文的, 如果出現了中文需要轉碼
// 可以呼叫encodeURIComponent方法
// URL中只可以出現字母/數字/下劃線/ASCII碼
res.push(encodeURIComponent(key)+"="+encodeURIComponent(obj[key]));
}
return res.join("&");
}
function ajax(url, obj, timeout, success, error) {
// 0.將物件轉換為字串
var str = objToStr(obj); // key=value&key=value;
// 1.創建一個異步物件
var xmlhttp, timer;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// 2.設定請求方式和請求地址
/*
method:請求的型別;GET 或 POST
url:檔案在服務器上的位置
async:true(異步)或 false(同步)
*/
xmlhttp.open("GET", url+"?"+str, true);
// 3.發送請求
xmlhttp.send();
// 4.監聽狀態的變化
xmlhttp.onreadystatechange = function (ev2) {
/*
0: 請求未初始化
1: 服務器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成,且回應已就緒
*/
if(xmlhttp.readyState === 4){
// 清除超時計時器
clearInterval(timer);
// 判斷是否請求成功
if(xmlhttp.status == 200){
// 5.處理回傳的結果
// console.log("接收到服務器回傳的資料");
success(xmlhttp);
}else{
// console.log("沒有接收到服務器回傳的資料");
error(xmlhttp);
}
}
}
// 判斷外界是否傳入了超時時間
if(timeout){
timer = setInterval(function () {
console.log("中斷請求");
xmlhttp.abort();
clearInterval(timer);
}, timeout);
}
}
當得到上述代碼以后,很明顯,又出現了新的問題:
- 上述代碼只實作了 GET 的請求方式,沒有實作 POST請求,我們可以增加一個 type 引數來進行選擇
- 加入 type 引數來選擇是 get 還是 post 時,考慮單詞的大小寫都能讓程式正確運行
- 在較低的ie瀏覽器版本,如果重繪時提交的資料沒有變化,則不會再次向服務器請求資料,而且取上次請求得到的資料,不能保證資料的實時更新
- 引數過多,如果引數順序不當會導致出現錯誤,可以參考jQuery中的Ajax方法,傳遞一個引數
2.5 最終版代碼
function objToStr(data) {
// 如果沒有傳參, 為了添加隨機因子,必須自己創建一個物件
data = data || {};
data.t = new Date().getTime();
var res = [];
for(var key in data){
// URL中只可以出現字母/數字/下劃線/ASCII碼
// 在URL中是不可以出現中文的, 如果出現了中文需要轉碼,
// 可以呼叫encodeURIComponent方法,對url中出現的中文進行轉碼
res.push(encodeURIComponent(key)+"="+encodeURIComponent(data[key]));
}
// 呼叫join方法將陣列轉化為字串,并且用 & 符號連接回傳給ajax方法
return res.join("&");
}
// 接受的僅僅為一個物件
function ajax(option) {
// 將物件轉換為字串
var str = objToStr(option.data); // key=value&key=value;
// 創建一個異步物件
var xmlhttp, timer;
// 針對ie瀏覽器的兼容性問題
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// 設定請求方式和請求地址
/*
method:請求的型別;GET 或 POST
url:檔案在服務器上的位置
async:true(異步)或 false(同步)
*/
// 將 type 轉化為小寫來判斷
if(option.type.toLowerCase() === "get"){
xmlhttp.open(option.type, option.url+"?"+str, true);
// 發送請求
xmlhttp.send();
}
else if(option.type.toLowerCase() === "post"){
// post請求是將資料放在請求頭中
xmlhttp.open(option.type, option.url,true);
// 注意點: 以下代碼必須放到open和send之間
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(str);
}
else{
// 既不是get 也不是post時 提示錯誤,函式結束執行
console.log("請輸入正確的請求方式");
return ;
}
// 4.監聽狀態的變化
xmlhttp.onreadystatechange = function (ev2) {
/*
監聽碼對應資訊
0: 請求未初始化
1: 服務器連接已建立
2: 請求已接收
3: 請求處理中
4: 請求已完成,且回應已就緒
*/
if(xmlhttp.readyState === 4){
// 清除超時計時器
clearInterval(timer);
// 判斷是否請求成功
if(xmlhttp.status == 200){
// 5.處理回傳的結果
// console.log("接收到服務器回傳的資料");
option.success(xmlhttp);
}else{
// console.log("沒有接收到服務器回傳的資料");
option.error(xmlhttp);
}
}
}
// 判斷外界是否傳入了超時時間
if(option.timeout){
timer = setInterval(function () {
console.log("中斷請求");
xmlhttp.abort();
clearInterval(timer);
}, option.timeout);
}
}
寫在最后:
雖然一些框架中都為我們封裝好了ajax方法,但是只有我們自己去寫這些方法,感受其中的程序,解決途中的問題,才能真正提高我們的代碼能力,在用這些方法的同時知道其中的原理,對我們了解這個知識點也更加有幫助,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/274531.html
標籤:其他
上一篇:英特爾第三代 Ice Lake 發布正面與 AMD EPYC PK,結果令人大跌眼鏡!
下一篇:hadoop集群配置
