Ajax+Node.js前後端交互最佳入門實踐(06)
6.XMLHttpRequest對象
XMLHttpRequest 是一個 API,它為客戶端提供了在客戶端和服務器之間傳輸數據的功能。它提供了一個通過 URL 來獲取數據的簡單方式,並且不會使整個頁面刷新。這使得網頁只更新一部分頁面而不會打擾到用戶。XMLHttpRequest 在 AJAX 中被大量使用。
6.1.創建XMLHttpRequest對象
6.1.1 XMLHttpRequest兼容性問題
XMLHttpRequest在ie6以下是以插件的形式來使用的,沒有內置在瀏覽器中,所以在ie6以下不能通過new XMLHttpRequest的形式來使用,在ie下可以通過new ActiveObject("Microsoft.XMLHTTP")來使用,因此,可以寫出這樣:
var xhr = null; if(window.XMLHttpRequest){ //標準模式下 xhr = new XMLHttpRequest(); }else{//ie6以下走這裏 xhr = new ActiveXobject(‘Microsoft.XMLHTTP‘); }
在很多地方也通過異常處理的形式來處理兼容。try...catch...finally語句語法結構:
try{ //嘗試著執行這段代碼 如果有錯就執行catch裏面的代碼 }catch(e){ //try裏面的錯誤信息都會被存放在 參數e裏面 }finally{ //不管是否有錯最終都要執行這段代碼 通常這裏都不寫 只是 try catch的組合 } try{ sdfs; alert(1); }catch(e){ alert(2); }finally{ alert(3) } //執行結果 先彈2 再彈3 try裏面的語句報錯
ajax對象兼容性寫法:
var xhr = null ; try{//標準下不會報錯 執行這裏的代碼 xhr = new XMLHttpRequest(); }catch(e){ ed //ie下try裏面的語句錯誤 執行這裏的代碼 }
6.2.open 方法
open方法和表單提交數據很相似
表單提交數據:
action: 數據提交的地址,如果不寫,默認提交到當前頁面
method: 數據提交的方式,有get和post兩種方式,默認使用get方式,url長度有限制,所以不要通過
get方式傳遞過長的數據,post方式理論上沒有長度限制,但是可以通過修改配置文件設置長度
enctype: 提交數據的格式,默認提交數據格式為:enctype="application/x-www-form-urlencoded"
open方法語法:
xhr.open("get","01.txt",true);
xhr為創建好的ajax對象
第一個參數: 打開方式,這裏的打開方式跟表單差不多,有get和post兩種方式,相當於method
第二個參數: 打開的地址,這裏就相當於表單裏的acthion屬性
第三個參數: 是否異步
同步:阻塞模式,當前一條代碼會影響後面代碼執行
異步:非阻塞模式,前面的 代碼不會影響後面代碼的執行
6.3.發送和獲取數據
通過send方法發送數據,通過監聽readystatechange事件來獲取數據
//發送請求---->相當於點擊回車鍵發送的過程 xhr.send(); //監聽請求狀態--->發送以後等待返回數據,網站展現出來 xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ alert(xhr.responseText); } }
responseText: 服務器返回的數據會存放到ajax對象的一個responseText屬性中 readyState:表示ajax的工作狀態,一共有5個狀態
狀態0: 表示ajax對象創建成功(初始化),但是還沒有調用open方法
狀態1:表示已調用send方法,正在發送數據(載入數據)
狀態2:send方法發送完成,已經收到響應內容(載入完成)
狀態3:表示正在解析內容(解析)(註:收到響應內容後,還需要解析內容)
狀態4:響應內容解析完成,可以使用數據了(註:狀態為4的時候說明所有流程已經完成,拿到數據了)
onreadyStatechang:這個事件用來監聽ajax工作狀態的,可能會被觸發多次,表示當狀態發生改變的時候被觸發
status: 表示服務器的狀態碼
通過以上幾個屬性的了解後,ajax獲取數據時的容錯處理可以寫成這樣:
xhr.onreadystatechange = function(){ if(xhr.readyState == 4 ){ if(xhr.status == 200){ alert(xhr.responseText); }else{ alert("出錯了:"+xhr.status); } } }
6.4.帶數據情況的處理
get方式發送數據,數據是放在url地址裏面發送過去的,在ajax中也通過這種形式傳送數據
//創建ajax對象 ---->相當於打開瀏覽器 var xhr = new XMLHttpRequest(); //打開要獲取文件的地址---->相當於輸入網址 xhr.open(‘get‘,‘/getData?username=xiaoqiang&age=19‘,true); //發送請求---->相當於點擊回車鍵發送的過程 xhr.send(); //監聽請求狀態--->發送以後等待返回數據,網站展現出來 xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ alert(xhr.responseText); } }
註意: 通過get方式發送請求在ie下會出現兩個問題,第一個就是緩存問題 第二就是亂碼問題,需要通過encodeURI()進行轉碼發送
post方式發送請求數據,數據是放在請求體裏面傳送過去的,在ajax中,數據放在send方法中傳送過去,並且要設置請求頭的類型
//創建ajax對象 ---->相當於打開瀏覽器 var xhr = new XMLHttpRequest(); //打開要獲取文件的地址---->相當於輸入網址 xhr.open(‘post‘,‘/getData‘,true); //發送請求---->相當於點擊回車鍵發送的過程 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded"); xhr.send(‘username=xiaoqiang&age=19‘); //監聽請求狀態--->發送以後等待返回數據,網站展現出來 xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status == 200){ alert(xhr.responseText); } }
舉個栗子: 1 ajax版用戶登錄認證
login.html文件內容
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .msg{ color: red; } </style> </head> <body> <form action=""> 用戶名: <input type="text" id="username"> <span class="msg"></span><br /> 密碼: <input type="password" id="password"> <br /> <input type="button" value="登錄" id="btn"> </form> <script> var oBtn = document.getElementById("btn"); var oUser = document.getElementById(‘username‘); var oPass = document.getElementById(‘password‘); var oSpan = document.getElementsByClassName(‘msg‘)[0]; oBtn.onclick = function () { var xhr = null; try { xhr = new XMLHttpRequest(); }catch(e){ xhr = new ActiveXobject(‘Microsoft.XMLHTTP‘); } xhr.open(‘post‘, ‘/login‘, true); xhr.setRequestHeader(‘content-type‘, ‘application/x-www-form-urlencoded‘); xhr.send(‘username=‘+oUser.value+‘&password=‘+oPass.value); xhr.onreadystatechange = function () { if(xhr.status === 200 && xhr.readyState === 4){ var obj = JSON.parse(xhr.responseText); if(obj.status === 0){ alert(obj.message); window.location.href = ‘http://nodeing.com‘; }else{ oSpan.innerHTML = obj.message; } } } } </script> </body> </html>
服務器端index.js中的代碼
var http = require(‘http‘); var url = require(‘url‘); var fs = require(‘fs‘); var querystring = require(‘querystring‘); var app = http.createServer(function (req, res) { res.setHeader(‘content-type‘, ‘text/html;charset=utf-8‘); var url_obj = url.parse(req.url); if(url_obj.pathname === ‘/login‘ && req.method===‘GET‘){ fs.readFile(‘./login.html‘,‘utf-8‘, function (err, data) { if(!err){ res.write(data); res.end(); } }) } // 處理ajax請求 if(url_obj.pathname === ‘/login‘ && req.method === ‘POST‘){ console.log(1); var post_data = ‘‘; req.on(‘data‘, function (chunk) { post_data += chunk; }); req.on(‘end‘, function () { var post_obj = querystring.parse(post_data); if(post_obj.username === ‘admin‘ && post_obj.password === ‘123456‘){ res.write(‘{"status":0, "message":"登錄成功"}‘); }else{ res.write(‘{"status":1, "message":"用戶名或者密碼錯誤"}‘); } res.end(); }) } }); app.listen(3000);
2 獲取後臺數據
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script type="text/javascript"> window.onload = function(){ var oBtn = document.getElementById("btn"); oBtn.onclick = function(){ //創建ajax對象 var xhr = null; try{ xhr = new XMLHttpRequest(); }catch(e){ xhr = new ActiveXobject(‘Microsoft.XMLHTTP‘); } //打開要獲取文件的地址 xhr.open(‘get‘,‘/getdata‘,true); //發送請求 xhr.send(); //alert(xhr.responseText); //監聽請求狀態 xhr.onreadystatechange = function(){ if(xhr.readyState == 4 && xhr.status==200){ var data = JSON.parse(xhr.responseText); var oUl = document.getElementById(‘ul1‘); for(var i=0;i<data.length;i++){ var oli = document.createElement(‘li‘); oli.innerHTML = data[i].title+‘[‘+data[i].time+‘]‘; oUl.appendChild(oli); } } } } } </script> </head> <body> <input type="button" id="btn" value="獲取數據" /> <ul id="ul1"> </ul> </body> </html>
app.js 代碼:
var http = require(‘http‘); var url = require(‘url‘); var fs = require(‘fs‘); var app = http.createServer(function (req, res) { res.setHeader(‘content-type‘, ‘text/html;charset=utf-8‘); var url_obj = url.parse(req.url); if(url_obj.pathname === ‘/‘){ fs.readFile(‘./index.html‘,‘utf-8‘, function (err, data) { if(!err){ res.write(data); res.end(); } }) } // 處理ajax請求 if(url_obj.pathname === ‘/getdata‘){ var arr = ‘[‘ + ‘{"title":"習大大出席國家科學技術獎勵大會1","time":"‘+new Date().toLocaleDateString()+‘"},‘ + ‘{"title":"習大大出席國家科學技術獎勵大會2","time":"‘+new Date().toLocaleDateString()+‘"},‘ + ‘{"title":"習大大出席國家科學技術獎勵大會3","time":"‘+new Date().toLocaleDateString()+‘"},‘ + ‘{"title":"習大大出席國家科學技術獎勵大會4","time":"‘+new Date().toLocaleDateString()+‘"}‘ + ‘]‘; res.write(arr); res.end(); } }); app.listen(3000);
Ajax+Node.js前後端交互最佳入門實踐(06)