AJAX入新手入門實例講解

AJAX入新手入門實例講解

本文參考或借鑑一些公開資料,特此說明。

AJAX( Asynchronous JavaScript and XML,異步的 JavaScript 和 XML),不是新的編程語言,而是一種使用現有標準的新方法。AJAX 最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新部分網頁內容。

同步的概念

同步,我的理解是一種線性執行的方式,執行的流程不能跨越。一般用於流程性比較強的程序,我們做的用戶登錄功能也是同步處理的,必須用戶通過用戶名和密碼驗證後才能進入系統的操作。同步可以看做是一個單線程操作,只要客戶端請求了,在服務器沒有反饋信息之前是一個線程阻塞狀態。

異步的概念

異步,是一種並行處理的方式,不必等待一個程序執行完,可以執行其它的任務。異步肯定是個多線程。在客戶端請求時,可以執行其他線程,並且在把這個線程存放在他的隊列裏面,有序的執行。在JavaScript中實現異步的方式主要有Ajax和H5新增的Web Worker。

而ajax就可以讓我們實現這裏所說的異步請求。

簡單地說,同步交互:客戶端發出一個請求後,需要等待服務器響應結束後,才能發出第二個請求;異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就可以發出第二個請求。

AJAX主要是實現頁面和 web 服務器之間數據的異步傳輸,因此學習練習使用AJAX需要使用Web服務器。

XMLHttpRequest 工作原理

傳統的web前端與後端的交互中,瀏覽器直接訪問Tomcat的Servlet來獲取數據。Servlet通過轉發把數據發送給瀏覽器。

當我們使用AJAX之後,瀏覽器是先把請求發送到XMLHttpRequest異步對象之中,異步對象對請求進行封裝,然後再與發送給服務器。服務器並不是以轉發的方式響應,而是以流的方式把數據返回給瀏覽器。

XMLHttpRequest異步對象會不停監聽服務器狀態的變化,得到服務器返回的數據,就寫到瀏覽器上,因爲不是轉發的方式,所以是無刷新就能夠獲取服務器端的數據。

使用js發起一個ajax請求過程,圖示如下:

說明:js發起一個ajax請求過程

首先let xhr = new XMLHttpRequest();,新建一個XMLHttpRequest對象。此時xhr對象的readyState=0,表示請求未初始化。

您需要調用xhr.open(method,url,async),告訴xhr請求的方式,URL,同步or異步,讓其初始化。如果執行完了這句,xhr.readyState=1,表示連接已經建立好了。

但是,如果您想發出請求,您就需要調用xhr.send()方法,如果是POST請求,您需要設置send()的參數,send(data)。調用過xhr.send()後,xhr.readyState就變成了2,請求已接收狀態,或者說我們已經發出了請求。

後面的幾個狀態,就不需要我們通過代碼去改變他了。我們的請求會通過網絡,到達指定服務器,服務器響應後,再通過網絡返回給我們。這個狀態,我們也無法通過代碼去改變。但是我們可以通過監聽函數onreadystatechange去獲取請求傳輸的進度。

當我們受到第一個字節開始,xhr.readyState=3。

在接收完全部響應數據後,請求完成,此時xhr.readyState=4。

之後處理……。

 

爲對上面介紹有一個感性認識,下面是一個比較完整而簡單的示例

包含兩個文件(放在同一目錄中):

一個名爲demo.txt的文本文件,內容如下:

呵呵,這是來自demo.txt的內容

一個名爲demo.html的網頁文件,內容如下:

<!DOCTYPE html>

<html>

<head>

<meta charset=" utf-8">

<meta name="author" content="http://www.softwhy.com/" />

<title>螞蟻部落</title>

<script>

function loadXMLDoc(){

  var xmlhttp;

  if (window.XMLHttpRequest){

    xmlhttp=new XMLHttpRequest();

  }

  else{

    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");

  }

  xmlhttp.onreadystatechange=function(){

    if(xmlhttp.readyState==4 && xmlhttp.status==200){

      document.getElementById("show").innerHTML=xmlhttp.responseText;

    }

  }

  xmlhttp.open("GET","demo.txt",true);

  xmlhttp.send();

}

window.οnlοad=function(){

  var obt=document.getElementById("bt");

  obt.οnclick=function(){

    loadXMLDoc();

  }

}

</script>

</head>

<body>

<div id="show">

  <h2>原來的內容</h2>

</div>

<input type="button" id="bt" value="查看效果"/>

</body>

</html>

 

用瀏覽器打開demo.html的網頁文件,點擊按鈕讀入demo.txt文本中的內容,參見下圖:

 

 

創建 XMLHttpRequest 對象的語法:

variable=new XMLHttpRequest();

XMLHttpRequest對象的常見屬性如下:

屬性

描述

onreadystatechange

存儲函數(或函數名),每當readyState的屬性改變時,就會調用該函數。

readyState

存有的XMLHttpRequest的狀態從0到4發生變化。
0:請求未初始化
1:服務器連接已建立
2:請求已接收
3:請求處理中
4:請求已完成,且響應已就緒

reponseText

以文本形式返回響應。

responseXML

以XML格式返回響應

status

將狀態返回爲數字(例如,“Not Found”爲404,“OK”爲200)

statusText

以字符串形式返回狀態(例如,“Not Found”或“OK”)

 

XMLHttpRequest對象的方法

XMLHttpRequest對象的重要方法如下:

方法

描述

abort()

取消當前請求。

getAllResponseHeaders()

以字符串形式返回完整的HTTP標頭集。

getResponseHeader( headerName )

返回指定HTTP標頭的值。

void open(method,URL)

打開指定獲取或交的方法和URL的請求。

void open(method,URL,async)

與上面相同,但指定異步或不。

void open(method,URL,async,userName,password)

與上面相同,但指定用戶名和密碼。

void send(content)

發送獲取請求。

setRequestHeader( label,value)

將標籤/值對添加到要發送的HTTP標頭。

 

下面給出實例

例1、利用ajax讀取xml文件中的數據

本例使用了兩個文件,一個是data.xml——充當服務端,一個是ajaxTest.html——充當客戶端。都可以用記事本建立,注意文件名的後綴(擴展名)。放在一個文件夾中。

data.xml內容如下:

<?xml version="1.0" encoding="utf-8"?>

<root>

    <data>

    這是一些樣本數據……它存儲在XML文件中,並由JavaScript檢索。

    </data>

</root>

 

ajaxTest.html內容如下:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>用Ajax開發Web應用程序之示例</title>

<script type="text/javascript">

<!--

//此函數將在電擊"View XML data"鏈接的時候執行

function ajaxRead(file){

 //xmlObj,負責客戶端和服務器中轉

 var xmlObj=null;

 /*

   測試不同對象的可用性

   不同的瀏覽器執行XMLHttpRequest對象的時候不同,所以定義"xmlObj"作爲XMLHttpRequest對象的時候,必須區別對待

   如果沒有XMLHttpRequest可用,函數以return結束來取消錯誤報告

 */

 if(window.XMLHttpRequest){

  xmlObj=new XMLHttpRequest();

 }else if(window.ActiveXObject){

  xmlObj=new ActiveXObject("Microsoft.XMLHTTP");

 }else{

  return;

 }

 /*

   每當XMLHttpRequest狀態改變時,onreadystatechange事件就觸發

   此事件共有5個狀態,從0到4

   [0]uninitialized未初始化(在XMLHttpRequest開始前)

   [1]loading(一旦初始化)

   [2]loaded(一旦XMLHttpRequest從服務器獲得響應)

   [3]interactive(當對象連接到服務器)

   [4]complete(完成)

 */

 /*

   readyState()方法用來獲得當前XMLHttpRequest的狀態

   狀態5[編號4]是用來確認數據是否可用的,如果"是",則執行updateObj方法

   此方法有2個參數:ID,填充的數據

 */

 /*

  xmlObj.responseXML屬性是一個DOM對象,對於XML文件來說,它有點像網頁中的"document"對象

  通過getElementsByTagName可以獲得XML文件中的任何節點

  xmlObj.responseXML.getElementsByTagName('data')[0]是獲得第1個名稱爲"data"的節點

  它返回XML節點,無數據的---得到節點裏的數據必須通過訪問此節點的屬性

  firstChild.data

  (firstChild獲得<data>節點之間的文本節點,而"data"屬性則是文本節點的實際文本)

 */

 /*

   xmlObj.open('GET',file,true);

   xmlObj.send('');

   這是ajaxRead函數中的最後一塊

   xmlObj的open方法打開一個通往服務器的連接(通過一個特殊的協議,這裏指定爲"GET"---也可以使用"POST"或其他)

   請求一個文件(在這裏,file變量---data.xml,是當作參數發送給了ajaxRead函數)

   並且JavaScript可以操控這個請求是否爲同步(false)或者異步(true,默認)

   這是異步JavaScript和XML,將可以使用默認的異步方法---當使用同步之後,這個程序將不能運行

   xmlObj.send('');

   簡單的發送了一個空字符串給服務器

   如果沒有這一行,xmlObj的readystate的值將不能爲4,使得頁面將不能更新

   這個發送方法可以被用於其它東西,但是此程序僅僅從服務器得到數據,並沒有發送數據給服務器,所以就到此爲止

 */

 xmlObj.onreadystatechange=function(){

  if(xmlObj.readyState==4){

   updateObj('xmlObj',xmlObj.responseXML.getElementsByTagName('data')[0].firstChild.data);

  }

 }

 xmlObj.open('GET',file,true);

 xmlObj.send('');

}

/*

  此函數更新在當前頁有新值的其他任何元素

  第1個參數,"obj",是當前頁中一個元素的id---這是被更新的對象

  第2個參數,"data",指明瞭將要替換"obj"對象的一個新的字符串

  正常地,它是一個檢查並且確認當前頁有含有id值爲"obj"的元素的很好的方法

*/

function updateObj(obj,data){

  //document.getElementById(obj).firstChild.data = data;

  document.getElementById(obj).innerHTML=data;

}

//-->

</script>

</head>

<body>

 <h1>用Ajax開發Web應用</h1>

 <p id="xmlObj">

  <a href="data.xml" title="查看XML數據" οnclick="ajaxRead('data.xml');this.style.display='none';return false">查看XML數據</a>

 </p>

</body>

</html>

用瀏覽器打開這個頁面(雙擊ajaxTest.html文件即可),結果如下所示:

 

要創建AJAX實例,需要使用服務器端,在這裏使用data.xml相當於服務器端上的文件。

前面提到過,AJAX主要是實現頁面和 web 服務器之間數據的異步傳輸,學習練習使用AJAX需要使用Web服務器,因此要想深入學習,就需要搭建Web服務器。

 

搭建Web服務器

Web服務器一般指網站服務器,是指駐留於因特網上某種類型計算機的程序,可以向瀏覽器等Web客戶端提供文檔,也可以放置網站文件,讓全世界瀏覽;可以放置數據文件,讓全世界下載。常見Web服務器有Apache+PHP+MySQL。在這裏我們使用nodejs+express搭建web服務器。

先安裝先安裝nodejs,進入下面這個nodejs中文網鏈接 下載nodejs

https://nodejs.org/zh-cn/

選擇對應的版本然後下載安裝(比較簡單就不多說了,如有疑惑可以百度),完了驗證下nodejs安裝是否成功。輸入node -v命令查看版本:

 

測試nodejs原生的HTTP服務器

新建一個目錄(也稱爲文件夾),例如在D:\NodeTest下新建一個myServer文件夾,在這個目錄中新建(可用記事本)一個serverA.js文件(文件名你自定,只要擴展名是.js就行),寫入如下代碼:

var http = require("http");            //導入http模塊

//開啓一個監聽事件,每次HTTP請求都會觸發這個事件

http.createServer(function(req, res){  //req用戶請求信息 res服務器響應信息

   res.write('<head><meta charset="utf-8"/></head>');   //設置編碼

   res.write("實驗測試!");      //設置響應體

   res.end();                           //結束事件

}).listen(3000);                      //設置監聽端口號

// 終端打印如下信息

console.log('Server running at http://127.0.0.1:3000 or http://localhost:3000 ');

 

用node 命令執行

在cmd中輸入 node D:\NodeTest\serverA.js

啓動服務,如下所示:

 

打開瀏覽器訪問 http://127.0.0.1:3000 或 http://localhost:3000,如下所示:

 

簡單例子運行成功了,這其實是用node.js搭建了一個服務器,然後來監聽端口的訪問事件,最後做出相應的迴應,需要指出的是,當我們關閉CMD或按CTRL+C鍵之後服務就關閉了。如果修改了nodejs服務器端的代碼,都需要重啓服務器纔會生效。

 

在此基礎上,就可以使用nodejs服務器

 

例、有註冊和登錄功能的服務器

建立一個目錄D:\AJAXTest2,再在此建立一個www目錄,將server.js放入AJAXTest2目錄,

將user.html和ajax.js放入www目錄,參見下圖:

 

server.js內容如下:

const http = require('http');

const fs = require('fs');

const querystring = require('querystring');

const urlLib = require('url');

var users = {};

var server = http.createServer(function (req, res) {

    //解析數據

    var str = '';

    req.on('data', function (data) {

        str += data;

    });

    req.on('end', function () {

        var obj = urlLib.parse(req.url, true);

        const url = obj.pathname;

        const GET = obj.query;

        const POST = querystring.parse(str);

        //區分——接口、文件

        if (url == '/user') { //接口

            switch (GET.act) {

                case 'reg':

                    //1.檢查用戶名是否已經有了

                    if (users[GET.user]) {

                        res.write('{"ok": false, "msg": "此用戶已存在"}');

                    } else {

                        //2.插入users

                        users[GET.user] = GET.pass;

                        res.write('{"ok": true, "msg": "註冊成功"}');

                    }

                    break;

                case 'login':

                    //1.檢查用戶是否存在

                    if (users[GET.user] == null) {

                        res.write('{"ok": false, "msg": "此用戶不存在"}');

                        //2.檢查用戶密碼

                    } else if (users[GET.user] != GET.pass) {

                        res.write('{"ok": false, "msg": "用戶名或密碼有誤"}');

                    } else {

                        res.write('{"ok": true, "msg": "登錄成功"}');

                    }

                    break;

                default:

                    res.write('{"ok": false, "msg": "未知的act"}');

            }

            res.end();

        } else { //文件

            //讀取文件

            var file_name = './www' + url;

            console.log(file_name);

            fs.readFile(file_name, function (err, data) {

                if (err) {

                    console.log(err)

                    res.write('404');

                } else {

                    res.write(data);

                }

                res.end();

            });

        }

    });

});

server.listen(8080);

//終端提示

console.log('Server running at  http://localhost:8080')

 

ajax.js內容如下:

function json2url(json){

    var arr=[];

    for(var name in json){

        arr.push(name+'='+json[name]);

    }

    return arr.join('&');

}

function ajax(json){

    json=json || {};

    if(!json.url)return;

    json.data=json.data || {};

    json.type=json.type || 'get';

    var timer=null;

    if(window.XMLHttpRequest){

        var oAjax=new XMLHttpRequest();

    }else{

        var oAjax=new ActiveXObject('Microsoft.XMLHTTP');

    }

    switch(json.type){

        case 'get':

            oAjax.open('GET',json.url+'?'+json2url(json.data),true);

            oAjax.send();

            break;

        case 'post':

            oAjax.open('POST',json.url,true);

            oAjax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');

            oAjax.send(json2url(json.data));

            break;

    }

    oAjax.onreadystatechange=function(){

        if(oAjax.readyState==4){

            clearTimeout(timer);

            if(oAjax.status>=200 && oAjax.status<300 || oAjax.status==304){

                json.success && json.success(oAjax.responseText);

            }else{

                json.error && json.error(oAjax.status);

            }

        }

    };

}

 

user.html內容如下:

<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8">

    <title></title>

    <script src="ajax.js" charset="utf-8"></script>

    <script type="text/javascript">

      window.οnlοad=function (){

        var oTxtUser=document.getElementById('user');

        var oTxtPass=document.getElementById('pass');

        var oBtnReg=document.getElementById('reg_btn');

        var oBtnLogin=document.getElementById('login_btn');

        oBtnLogin.οnclick=function (){

          ajax({

            url: '/user',

            data: {act: 'login', user: oTxtUser.value, pass: oTxtPass.value},

            type: 'get',

            success: function (str){

              var json=eval('('+str+')');

              if(json.ok){

                alert('登錄成功');

              }else{

                alert('登錄失敗:'+json.msg);

              }

            },

            error: function (){

              alert('通信錯誤');

            }

          });

        };

        oBtnReg.οnclick=function (){

          ajax({

            url: '/user',

            data: {act: 'reg', user: oTxtUser.value, pass: oTxtPass.value},

            type: 'get',

            success: function (str){

              var json=eval('('+str+')');

              if(json.ok){

                alert('註冊成功');

              }else{

                alert('註冊失敗:'+json.msg);

              }

            },

            error: function (){

              alert('通信錯誤');

            }

          });

        };

      };

    </script>

  </head>

  <body>

    用戶:<input type="text" id="user"><br>

    密碼:<input type="password" id="pass"><br>

    <input type="button" value="註冊" id="reg_btn">

    <input type="button" value="登錄" id="login_btn">

  </body>

</html>

 

先cd到D:\AJAXTest2目錄

cd /d D:\AJAXTest2

啓動  node server.js

 

瀏覽器訪問localhost:8080/user.html

 

輸入用戶名和密碼,開始註冊或登錄,試試了。

 

關於express

express 是nodejs的一個web框架,使用express,能夠更便捷的使用nodejs.

express-generator是express應用生成器,相當於express 的骨架,進入一個web項目中後,使用express projectname命令,能快速構建projectname這個應用的目錄結構。

npm install express --save -g

npm install express-generator --save -g 

 

之後,在找到其所在位置:

 

現在可以使用express框架構建express項目

在cmd中使用命令:express ‘你的項目名’ -e

其中,-e 表示使用EJS模板。

例如:

express myStudy -e

 

安裝成功後就可以使用express框架構建項目了,在當前目錄中生成了一個與項目名相同目錄。最後有3個選項,先不深究,意思是:

改變目錄:cd expressDemo

安裝依賴:npm install

運行應用程序:npm start

關於express就不進一步介紹了,感興趣的朋友可以參考他文。

 

下面介紹jQueryd的Ajax方法。

 

jQueryd的Ajax方法

$.ajax()方法中的參數很多,我在實例中使用的只是一小部分,這裏只介紹實例中所需要的參數的使用,其餘更多參數還將繼續學習。

$.ajax({         

          url:"發送請求(提交或讀取數據)的地址",

         dataType:"預期服務器返回數據的類型", 

         type:"請求方式",

         async:"true/false",

         data:{發送到/讀取後臺(服務器)的數據},

         success:function(data){請求成功時執行},     

         error:function(){請求失敗時執行}

});

 

說明: 這些參數均爲選填,如果不設置,按默認值處理。

<1> url  默認爲當前頁地址

<2> dataType 可用類型:

(如果不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,並作爲回調函數參數傳遞)

 

xml:返回XML文檔,可用JQuery處理。

html:返回純文本HTML信息。

script:返回純文本JavaScript代碼。

json:返回json數據。

jsonp:(JSON with Padding) 是 json 的一種"使用模式",可以讓網頁從別的域名(網站)那獲取資料,即跨域讀取數據。

text:返回純文本字符串。

說明:對於json和jsonp的區別,本小白暫時沒有深入瞭解,目前只知道jsonp可以跨域讀取數據,有待進一步學習~

 

<3> type 可用類型主要爲post和get兩種(默認爲get)

 

get:從指定的資源請求數據(從服務器讀取數據)

post:向指定的資源提交要被處理的數據(向服務器提交數據)

 

<4> async 異步方式,默認爲true,即異步方式。當設置爲false時,爲同步方式。

 

異步方式:ajax執行後,會繼續執行ajax後面的腳本,直到服務器端返回數據後,觸發ajax裏的success方法,這時候執行的是兩個線程。

同步方式:在沒有返回值之前,同步請求將鎖住瀏覽器,用戶其它操作必須等待請求完成纔可以執行。

說明:這裏的同步和異步有待深入理解,以下實例均使用默認的異步方式

 

<5> data 請求的數據,{ }中可以填入多項數據。如果不填(一般爲get請求),則讀取對應地址的全部數據,此時可以在console中通過console.log(res)顯示數據情況。

<6> success 和 error 兩個函數 一般需要設置,方便確定請求是否成功,以及請求成功後的提示或是對數據的處理和顯示。

 

例、實現在頁面上輸入一個地址,點擊獲取經緯度,彈出該地址的經緯度。

(本例來源:https://blog.csdn.net/Yuan_mingyu/article/details/86748591

url=“https://restapi.amap.com/v3/geocode/geo” key:“7486e10d3ca83a934438176cf941df0c”

(此處的key值是從此地址請求數據所需的,爲data數據中的一項,直接使用即可)

 

<!DOCTYPE html>

<html>

<head>

<meta charset=" utf-8">

<meta name="author" content="http://www.softwhy.com/" />

<title>查詢經緯度</title>

<!-- js部分 -->

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>

<script type="text/javascript">

    function showAdress()

 {

     var str = document.getElementById("text").value;   

    $.ajax

    ({

        url: "https://restapi.amap.com/v3/geocode/geo",

        dataType: "json",

        type: "get",

        data: {

                address: str,             

                   key: "7486e10d3ca83a934438176cf941df0c",

               },

        success:function(data){

               alert(data.geocodes[0].formatted_address+"經緯度:"+data.geocodes[0].location);

               console.log(data);  //在console中查看數據

           },

        error:function(){

               alert('failed!');

        },

    });

 }

</script>

</head>

<body>

<!-- css部分 -->

   <style type="text/css">

          .button{

              width: 100px;

              height: 29px;

              font-size: 16px;

              color: white;

              background-color: black;

              padding: 0;

              vertical-align: top;

              border: 0;

          }

          .textbox{

              height: 25px;

              padding: 0;

              vertical-align: top;

          }

          span{

              font-size: 16px;

              height: 29px;

              line-height: 29px;

          }

      </style>

<p>利用 https://restapi.amap.com/v3/geocode/geo服務 </p>

<!-- div部分 -->

<div>

          <form name="form">

              <span>輸入地址:</span><input id="text" class="textbox" type="text"/>

              <input class="button" type="button" value="獲取經緯度" οnclick="showAdress()"/>

          </form>

</div>

</body>

</html>

 

將上述代碼,保存文件名爲:jQuery的Ajax實例.html。用瀏覽器打開這個頁面(雙擊“jQuery的Ajax實例.html”文件即可),結果如下所示:

 

AJAX官網:

http://api.jquery.com/category/ajax/

AJAX教程

https://www.softwhy.com/qiduan/ajax_source/

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章