1. 程式人生 > >Ajax+Node.js前後端交互最佳入門實踐(06)

Ajax+Node.js前後端交互最佳入門實踐(06)

國家 key msg readfile ctu chan 服務器 red child

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)