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/

 

 

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