零基础学习AJAX之AJAX的简介和基础
零基础学习AJAX之AJAX的简介和基础
发布时间:2016-12-29 来源:查字典编辑
摘要:本节简介(异步链接服务器对象)XMLHTTPRequest以及AJAX的简介。AJAX即“AsynchronousJavascriptAnd...

本节简介(异步链接服务器对象)XMLHTTPRequest以及AJAX的简介。

AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML)。 AJAX有四个方面的好处:1.即减轻了服务器的负担。2带来了更好的用户体验。3.基于标准被广泛的支持。4.拥有更好的页面呈现和数据分离。

技术名称技术说明

javascriptjavascript是通用的脚本语言,AJAX是用javascript编写的

css用户界面的样式通过css来修改

DOMDOM通过javascript修改DOM,ajax可以在运行时改变用户界面,或者局部更新页面中的某个节点。

XMLHttpRequestXMLHttpRequest对象 XMLHttpRequest对象允许web程序员从web服务器以后台的方式获取数据。数据的个数通常是XML或者是文本。

从上面我们看出,javascript就想胶水一样将各个部分粘贴在一起,例如通过javascript操作BOM改变刷新用户界面,通过修改className来改变css样式风格

1.异步对象连接服务器

不严谨的说,ajax是一个简单的多线程,它能够是用户在前台多种操作而不间断。ajax异步交互在后台默默的工作着 在web中异步访问是通过XMLHttpRequest对象来实现的,该对象最早是在ie5被作为activeX控件引入的。随后各个浏览器纷纷支持该异步对象,首先必须创建对象。代码如下:

复制代码 代码如下:

var xmlHttp;

function createXMLHrrpRequest() {

if (window.ActiveXObject)

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

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

}

该对象是先创建了一个全局变量xmlHttp,留以后函数中使用。另外创建异步对象函数createXMLHrrpRequest()

该过程用到了if语句方法,如果是IE采用window.ActiveXobject方法,如果不是,则用XMLHttpRequest方法创建函数。

在创建完异步对象后,自然是使用该对象连接服务器,该对象有一系列十分有用的属性和方法。

属性/方法说明

abort()取消请求

getAllResponseHeaders()获取指定的Http头

open(method,url)创建请求,method指定请求类型,GET POST

send()发送请求

setRequestHeader()指定请求的http头

onreadystatechange发生任何状态变化时的事件控制对象

readyState

请求的状态

0为尚未初始化

1为正在发送请求

2为请求完成

3为请求成功,正接收数据。

4为接收数据成功

responseText服务器返回文本

responseXML服务器返回xml

status

服务器返回的http请求响应值,常用的有

200表示请求成功

202表示请求被接收,但处理未完成

400表示错误的请求

404表示资源未找到

500表示内部服务器错误,如aspx代码错误

创建完XMLHttpRequest对象后首先利用open()方法建立一个请求,并向服务器发送,该方法的完整表示式如下:

open(methond,url,asynchronous,user,password)

其中,method表示请求的类型,通长为GET,POST。

url即请求的地址,可以是绝对地址,也可以是相对地址。

asynchronous是一个布尔值,表示是否为异步请求,默认值为异步请求true。

user、password分别为可选的用户名、密码。

创建了异步对象后,要建立一个到服务器的请求可使用如下代码:

xmlHttp.open("GET","1-1.aspx",true);

以上代码用get方法请求的相对地址为9-1.aspx的页面,方式是异步的。在发出了请求后便需要请求的状态readyState属性来判断请求的情况,如果该属性变化了,就会触发onreadystatechange事件,因此通常的代码如下:

复制代码 代码如下:

<script type="text/javascript">

xmlHttp.onRecorderStateChange = function(){

if(xmlHttp.readyState == 4)

//执行相关代码

}

</script>

也就是直接编写onRecorderStateChange的事件函数,如果readyState的状态为4(数据接收成功)则继续操作。但是通常情况下,不但需要判断请求的状态,还要判断服务器返回的状态status,因此上述代码改为

复制代码 代码如下:

<script type="text/javascript">

xmlHttp.onRecorderStateChange = function(){

if(xmlHttp.readyState == 4&& xmlHttp.status==200)

//执行相关代码

}

</script>

以上两段代码仅仅只是建立了请求,还需要使用send()方法来发送请求,该方法的原型如下:

send(body);

改方法仅有一个参数body,它表示要向服务器发送的数据,其格式为查询字符串的形式,例如:

var body = "myName=isaac&age=25";

如果再open中指定的是get方式,则这些参数作为查询字符串提交,如果指定的是post方式,则作为HTTP的POST方法提交。对于send()而言。body参数是必须的,如果不发送任何数据,则可以使用

xmlHttp.send(null)

特别的,如果使用POST方法进行提交请求,那么在发送之前必须使用以下语句来设置HTTP的头,语法如下:

xmlHttp.setRequestHeader("content-Type","application/x-www-form-urlencoded;")

服务器在收到客户端请求之后,根据请求返回相应的结果,这个结果通常为两种形式,一种是文本形式,存储在responseText中;另一种是XML格式,存储在responseXML中。客户端程序可以对前者进行字符串的处理,对后者进行DOM相关的处理,例如可以对服务器返回值做如下的处理:

alert("服务器返回:"+xmlHttp.responseText);

上述整个异步连接服务器的过程如下:

复制代码 代码如下:

<body>

<script type="text/javascript">

var xmlHttp;

function createXMLHttpRequest() {

if (window.ActiveXObject)

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

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

}

function startRequest() {

createXMLHttpRequest();

xmlHttp.open("GET", "http://study.ahthw.com/ajaxresponse/1-1.aspx", true);

xmlHttp.onreadystatechange = function() {

if (xmlHttp.readyState == 4 && xmlHttp.status == 200)

alert("服务器返回: " + xmlHttp.responseText);

}

xmlHttp.send(null);

}

</script>

<input type="button" value="测试异步通讯">

</body>

为了解决异步连接ie缓存问题,需要在真实地址加一个与时间毫秒相关的参数,使得每次请求的地址都不一样。而该参数服务器确是不需要的。

复制代码 代码如下:

var sUrl = "1-1.aspx"+new Date().getTime();//地址不断变化

XMLHttp.open("GET",sUrl,true);

2.GET和POST模式

上面的实例中,除了请求异步服务器以外,并没有向服务器发送额外的数据,通常在html请求中有get和post模式,这两种模式都可以作为异步请求发送数据的方式。

如果是GET请求,则直接把数据放入异步请求的URL地址中,而send方法不发送任何数据,例如:

复制代码 代码如下:

var queryString = "firstName=isaac&birthday=0226";

var sUrl = "1-1.aspx" + queryString + "×tamp" + new Date().getTime();

xmlHttp.open("GET", sUrl);

xmlHttp.send(null); //该语句只发送null

如果是POST模式,则是把数据统一在send()方法中送出,请求地址没有任何信息,并且必须设置请求的文件头,例如:

复制代码 代码如下:

<script language="javascript">

var queryString = "firstName=isaac&birthday=0226";

var sUrl = "1-1.aspx" + queryString + "×tamp" + new Date().getTime();

xmlHttp.open("POST", sUrl);

xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

xmlHttp.send(queryString); //该语句负责发送数据

</script>

实例

为了更清楚地演示GET和POST的区别,编写示例代码,首先创建两个文本框用于输入用户姓名和生日,并建立两个按钮分别用于GET和POST两个方法来发送异步请求

复制代码 代码如下:

<form>

<p><input type="text" id="firstName"/></p>

<p><input type="text" id="birthday" /></p>

</form>

<input type="button" value="GET">

<input type="button" value="POST">

其中用户填写的数据统一用函数createQueryString()编写,需要时予以调运,代码如下

复制代码 代码如下:

function crrateQueryString() {

var firstName = document.getElementById("firstName").value;

var birthday = document.getElementById("birthday").value;

var queryString = "firstName=" + firstName + "&birthday=" + birthday;

return queryString;

}

服务器接收到请求数据后根据不同的时刻返回相应的文本,客户端接收到文本后显示在相应的div快中,代码如下

复制代码 代码如下:

function handleStateChange() {

if (xmlHttp.readyState == 4 && xmlHttp.state == 200) {

var responseDiv = document.getElementById("serverResponse");

responseDiv.innerHTML = xmlHttp.responseText;

}

}

GET和POST各建立自己的函数doRequestUsingGET()和doRequestUsingPOST()。

完整代码如下:

复制代码 代码如下:

<script type="text/javascript">

var xmlHttp;

function createXMLHttpRequest() {

if (window.ActiveXObject)

xmlHttp = new ActiveXObject("Microsoft.XMLHttp");

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

}

function createQueryString() {

var firstName = document.getElementById("firstName").value;

var birthday = document.getElementById("birthday").value;

var queryString = "firstName=" + firstName + "&birthday=" + birthday;

return encodeURI(encodeURI(queryString)); //两次编码解决中文乱码问题

}

function doRequestUsingGET() {

createXMLHttpRequest();

var queryString = "1-3.aspx";

queryString += createQueryString() + "×tamp=" + new Date().getTime();

xmlHttp.onreadystatechange = handleStateChange;

xmlHttp.open("GET", queryString);

xmlHttp.send(null);

}

function doRequestUsingPOST() {

createXMLHttpRequest();

var url = "1-3.aspx" + new Date().getTime();

var queryString = createQueryString();

xmlHttp.open("POST", url);

xmlHttp.onreadystatechange = handleStateChange;

xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

xmlHttp.send(queryString);

}

function handleStateChange() {

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

var responseDiv = document.getElementById("serverResponse");

responseDiv.innerHTML = decodeURI(xmlHttp.responseText); //解码

}

}

</script>

<form>

<input type="text" id="firstName" />

<br>

<input type="text" id="birthday" />

</form>

<form>

<input type="button" value="GET" />

<br>

<input type="button" value="POST" />

</form>

<div id="serverResponse"></div>

服务器端主要是根据用户输入以及请求的类型返回不同的字符串

复制代码 代码如下:

<%@ Page Language="C#" ContentType="text/html" ResponseEncoding="gb2312" %>

<%@ Import Namespace="System.Data" %>

<%

if(Request.HttpMethod == "POST")

Response.Write("POST: " + Request["firstName"] + ", your birthday is " + Request["birthday"]);

else if(Request.HttpMethod == "GET")

Response.Write("GET: " + Request["firstName"] + ", your birthday is " + Request["birthday"]);

%>

从以上代码看出POST和GET都发送了数据异步请求,通常在数据不多的时候使用GET,在数据较多的时候使用POST。

在使用PSOT发送中文字符时,post接收会乱码,使用GET发送中文字符正常。这是因为异步对象xmlHttp在处理返回的responseText的时候,是按照UTF-8编码的。

通常的解决办法是escape()对发送的数据进行编码,然后在返回的responseText再使用unescape()进行解码。然而在javascript编程中通常不推荐escape()和unescape()。而推荐使用encodeURI()和decodeURI()。这里要正常运行,必须对发送的数据进行两次encodeURI()编码。

代码如下

复制代码 代码如下:

function createQueryString(){

var firstName =document.getElementById("firstName").value;

var birthday =document.getElementById("birthday").value;

var queryString = "firstName="+firstName +"&birthday="+birthday;

return encodeURI(encodeURI(queryString)); //两次编码解决中文乱码问题

}

而且在返回数据responeText时再进行一次解码,代码如下

复制代码 代码如下:

function handleStateChange(){

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

var responeDiv =document.getElementById(serverResponse);

responeDiv.innerHTML = decodeURI(XMLHttp.responseText);//编码

}

}

这样POST模式下也能使用中文了。

3.服务器返回xml

XML是一种可扩展标记语言(Extensible Markup Language),它是一种可自定义标记的语言,用来克服html局限,按照实际功能来看,xml主要用于数据存储。

在ajax中,服务器如果返回XML,可通过异步对象的responseXML属性来获取,开发者可以利用DOM的作用方法进行处理。

假设服务器返回

复制代码 代码如下:

<"1.0" encoding="gb2312"?>

<list>

<caption>Member List</caption>

<member>

<name>isaac</name>

<class>W13</class>

<birth>Jun 24th</birth>

<constell>Cancer</constell>

<mobile>1118159</mobile>

</member>

<member>

<name>fresheggs</name>

<class>W610</class>

<birth>Nov 5th</birth>

<constell>Scorpio</constell>

<mobile>1038818</mobile>

</member>

<member>

<name>girlwing</name>

<class>W210</class>

<birth>Sep 16th</birth>

<constell>Virgo</constell>

<mobile>1307994</mobile>

</member>

<member>

<name>tastestory</name>

<class>W15</class>

<birth>Nov 29th</birth>

<constell>Sagittarius</constell>

<mobile>1095245</mobile>

</member>

<member>

<name>lovehate</name>

<class>W47</class>

<birth>Sep 5th</birth>

<constell>Virgo</constell>

<mobile>6098017</mobile>

</member>

<member>

<name>slepox</name>

<class>W19</class>

<birth>Nov 18th</birth>

<constell>Scorpio</constell>

<mobile>0658635</mobile>

</member>

<member>

<name>smartlau</name>

<class>W19</class>

<birth>Dec 30th</birth>

<constell>Capricorn</constell>

<mobile>0006621</mobile>

</member>

<member>

<name>tuonene</name>

<class>W210</class>

<birth>Nov 26th</birth>

<constell>Sagittarius</constell>

<mobile>0091704</mobile>

</member>

<member>

<name>dovecho</name>

<class>W19</class>

<birth>Dec 9th</birth>

<constell>Sagittarius</constell>

<mobile>1892013</mobile>

</member>

<member>

<name>shanghen</name>

<class>W42</class>

<birth>May 24th</birth>

<constell>Gemini</constell>

<mobile>1544254</mobile>

</member>

<member>

<name>venessawj</name>

<class>W45</class>

<birth>Apr 1st</birth>

<constell>Aries</constell>

<mobile>1523753</mobile>

</member>

<member>

<name>lightyear</name>

<class>W311</class>

<birth>Mar 23th</birth>

<constell>Aries</constell>

<mobile>1002908</mobile>

</member>

</list>

下面利用异步对象获取该XML,并将所有的项都罗列在表格中,初始化对象的方法与获取文本完全相同,代码如下:

复制代码 代码如下:

var xmlHttp;

function createXMLHttpRequest() {

if (window.ActiveXObject)

xmlHttp = new ActiveXObject("Mincrosoft,XMLHttp");

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

}

当用户单击按钮时发生异步请求,并获取responseXML对象,代码如下

复制代码 代码如下:

function getXML(addressXML) {

var sUrl = addressXML + "" + new Date();

createXMLHttpRequest();

xmlHttp.onRecorderStateChange = handleStateChange;

xmlHttp.open("GET", url);

xml.send(null);

}

function handleStateChange() {

if (xmHttp, readyState == 4 && xmlHttp.status == 200)

DrawTable(xmlHttp.responseXML); //responseXML获取到xml文档

}

其中DrawTable()为后勤处理XML的函数,将服务器返回的XML对象responseXML直接作为参数传递,HTML部分如下:

复制代码 代码如下:

<input type="button" value="获取XML"><br><br>

<table summary="list of members in EE Studay" id="member">

<tr>

<th scope="col">Name</th>

<th scope="col">Class</th>

<th scope="col">Birthday</th>

<th scope="col">Constellation</th>

<th scope="col">Mobile</th>

</tr>

</table>

当用户单击按钮时出发getXML(),并将xml地址1-4.xml作为参数传入

而函数DrawTable()的任务就是把XML中的数据拆分,并重新组装到表格"member"中,代码如下:可以看到处理XML的方法与DOM处理HTML完全相同

复制代码 代码如下:

function DrawTable(myXML) {

//用DOM方法操作XML文档

var oMembers = myXML.getElementsByTagName("member");

var oMember = "",

sName = "",

sClass = "",

sBirth = "",

sConstell = "",

sMobile = "";

for (var i = 0; i < oMembers.length; i++) {

oMember = oMembers[i];

sName = oMember.getElementsByTagName("name")[0].firstChild.nodeValue;

sClass = oMember.getElementsByTagName("class")[0].firstChild.nodeValue;

sBirth = oMember.getElementsByTagName("birth")[0].firstChild.nodeValue;

sConstell = oMember.getElementsByTagName("constell")[0].firstChild.nodeValue;

sMobile = oMember.getElementsByTagName("mobile")[0].firstChild.nodeValue;

//添加一行

addTableRow(sName, sClass, sBirth, sConstell, sMobile);

}

}

其中addTableRow()函数将拆分出来的每一组XML数据组装成表格<table>的一行,添加到页面中。代码如下:

复制代码 代码如下:

function addTableRow(sName, sClass, sBirth, sConstell, sMobile) {

//表格添加一行的相关操作

var oTable = document.getElementById("member");

var oTr = oTable.insertRow(oTable.rows.length);

var aText = new Array();

aText[0] = document.createTextNode(sName);

aText[1] = document.createTextNode(sClass);

aText[2] = document.createTextNode(sBirth);

aText[3] = document.createTextNode(sConstell);

aText[4] = document.createTextNode(sMobile);

for (var i = 0; i < aText.length; i++) {

var oTd = oTr.insertCell(i);

oTd.appendChild(aText[i]);

}

}

网站中实际返回xml的工作通常是由asp.net jsp php等服务器脚本动态生成的,换句话说,xmlHttp.open()中的URL地址仍然.aspx等动态页面的后缀,它们返回的XML是用户请求生成的。

4.处理多个异步请求

而实际页面中往往不止一个异步请求,比如在一个表单中,很多单元格都需要发生异步请求来验证,再加上网速的影响,第一个异步请求尚未完成,很可能就已经被第2个请求覆盖。

页面内容不做多介绍,我们发现,发送的第一个请求没有响应,因为它被第二个请求覆盖了。

通常解决的办法是将xmlHttp对象作为局部变量来处理,并且在收到服务器返回值后手动将其删除。如下所示:

复制代码 代码如下:

function getData(oServer, oText, oSpan) {

var xmlHttp; //处理为局部变量

if (window.ActiveXObject)

xmlHttp = new ActiveXObject("Microsoft.XMLHttp");

else if (window.XMLHttpRequest)

xmlHttp = new XMLHttpRequest();

var queryString = oServer + "";

queryString += createQueryString(oText) + "×tamp=" + new Date().getTime();

xmlHttp.onreadystatechange = function() {

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

var responseSpan = document.getElementById(oSpan);

responseSpan.innerHTML = xmlHttp.responseText;

delete xmlHttp; //收到返回结构后手动删除

xmlHttp = null;

}

}

xmlHttp.open("GET", queryString);

xmlHttp.send(null);

}

以上就是本文的全部内容了,虽然有点长,但是还是希望小伙伴们能够好好的读一读,这对于学好ajax非常重要,希望大家能够喜欢。

推荐文章
猜你喜欢
附近的人在看
推荐阅读
拓展阅读
相关阅读
网友关注
最新AJAX相关学习
热门AJAX相关学习
编程开发子分类