Ajax快速入门

一、什么是AJAX?

       AJAX的意思就是异步的JavaScript和XML。简而言之,它是使用XMLHttpRequest对象与服务器端通信的脚本语言。它可以发送及接收各种格式的信息,包括JSON、XML、HTML和文本文件。AJAX最为吸引人的就是它的“异步”特性,这意味着AJAX可以无需刷新页面而与服务器端进行通信。允许你根据用户事件来更新部分页面内容。

可以考虑的两个特性:

向服务器端发送请求,而不用重新加载页面。

从服务器端接收数据并处理。


第一步:如何发送一个HTTP请求

      需要通过XMLHttpRequest实现使用JavaScript向服务器端发送一个HTTP请求。而Internet Explorer(IE)中引入一个名为XMLHTTP的ActiveX对象实现与XMLHttpRequest相同的功能,Mozilla、Safari和其他浏览器则使用XMLHttpRequest。

如果要兼容各个浏览器的话,可以这样来做:

var httpRequest;

if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...

httpRequest = new XMLHttpRequest();

} else if (window.ActiveXObject) { // IE 6 and older

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

}

注意:出于演示目的,上面创建XMLHTTP实例是简化了的代码。关于更加真实的例子,请参阅本文的第三步。

接下来,当接收到服务器端响应时,需要告诉HTTP请求对象使用JavaScript函数来处理响应。将XMLHttpRequest对象的onreadystatechange属性设置为该函数的名称,当请求的状态变化时,该函数会被调用。

httpRequest.onreadystatechange = nameOfTheFunction;

注意:该函数名没有传递参数的括号和参数,这表示只是分配了一个函数的引用,而不是真正调用该函数。当然,也可以动态定义一个匿名函数,这样可以实时地处理响应。

httpRequest.onreadystatechange = function(){

// process the server response

};

在处理完服务器端的响应之后,我们就可以调用XMLHttpRequest对象的open()和send()方法向服务器端发送请求了。

httpRequest.open('GET', 'http://www.example.org/some.file', true);

httpRequest.send(null);

open()方法的第一个参数:HTTP请求方法 - GET、POST、HEAD及任何服务器端支持的方法。根据HTTP标准保持大写,否则一些浏览器(例如火狐)可能无法处理请求。关于HTTP请求方法的更多信息,你可以查看W3C规范

open()方法的第二个参数:请求的URL。出于安全考虑,不能调用第三方域的页面内容。当调用open()方法时,一定确认使用相同域名内的页面,否则会得到“permission denied”的错误提示。常见的错误是使用domain.tld访问网站,却使用www.domain.tld来请求页面。如果真的需要发送一个请求到另一个域的话,可以查看HTTP访问控制

open()方法的第三个参数:可选,是否是异步请求。如果是true(默认值),表示是异步请求。

send()方法的参数表示当请求为POST时,向服务器端发送请求的数据内容。如果发送的是表单数据格式的话,服务器端可以向字符串一样地解析。

"name=value&anothername="+encodeURIComponent(myVar)+"&so=on"

向服务器端发送的数据格式也可以是JSON、SOAP等格式。

注意:如果使用POST方式发送数据的话,在调用send()方法前,需要设置请求的MIME类型。:

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


第二步:处理服务器端的响应

当发送请求时,已经定义了一个函数来处理响应。

httpRequest.onreadystatechange = nameOfTheFunction;

这个函数可以做什么呢?首先,该函数需要检查请求的状态。如果状态值为4的话,这表示接收到完成的服务器端响应,可以继续处理。

if (httpRequest.readyState === 4) {

// everything is good, the response is received

} else {

// still not ready

}

readyState的值列表如下:

0 - 未初始化

1 - 正在加载

2 - 加载完毕

3 - 交互中

4 - 完成

接下来需要检查HTTP服务器端响应的状态代码,W3C网站 列出了所有的状态代码。下面的例子中,通过是否为200 OK的状态码来判断AJAX调用是否是成功的。

if (httpRequest.status === 200) {

// perfect!

} else {

// there was a problem with the request,

// for example the response may contain a 404 (Not Found)

// or 500 (Internal Server Error) response code

}

在检查了请求的状态和响应的状态码后,就可以接收服务器端发送的数据并处理。有两种选项访问这些数据:

httpRequest.responseText - 将服务器端响应作为文本字符串返回

httpRequest.responseXML - 将响应作为一个XMLDocument对象返回,该对象可以使用JavaScript DOM函数进行遍历。

注意,上述步骤只有异步请求(open()方法的第三个参数设置为true)时才是有效的。如果使用同步请求的话,是不需要指定函数的。在调用send()方法后就可以访问到服务器端返回的数据,因为脚本会停止并等待服务器端的响应。

第三步:一个简单的例子

下面来做一个简单的HTTP请求。JavaScript将请求一个包含“I’m a test.”文本的“test.html”HTML文档,然后使用alert()方法打印test.html文件的内容。

Make a request

(function() {

var httpRequest;

document.getElementById("ajaxButton").onclick = function() { makeRequest('test.html'); };

function makeRequest(url) {

if (window.XMLHttpRequest) { // Mozilla, Safari, ...

httpRequest = new XMLHttpRequest();

} else if (window.ActiveXObject) { // IE

try {

httpRequest = new ActiveXObject("Msxml2.XMLHTTP");

}

catch (e) {

try {

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

}

catch (e) {}

}

}

if (!httpRequest) {

alert('Giving up :( Cannot create an XMLHTTP instance');

return false;

}

httpRequest.onreadystatechange = alertContents;

httpRequest.open('GET', url);

httpRequest.send();

}

function alertContents() {

if (httpRequest.readyState === 4) {

if (httpRequest.status === 200) {

alert(httpRequest.responseText);

} else {

alert('There was a problem with the request.');

}

}

}

})();

在这个例子中:

在浏览器中用户单击“Make a request”链接;

事件处理器调用makeRequest()方法,通过向该函数传递的参数,请求一个处在同一目录中的“test.html”HTML文件;

请求后,(onreadystatechange)执行 alertContents()方法;

alertContents()方法用于检查如果正确地接收到响应,利用alert()方法打印“test.html”文件包含的内容。

注意:如果你发送一个请求后返回的是一段XML代码,而不是一个静态的XML文件的话,在Internet Explorer中必须设置一些响应头。如果没有设置响应头“Content-Type: application/xml”的话,当试图访问XML元素时IE将抛出一个”Object Expected”的JavaScript错误。

注意:如果没有设置头“Cache-Control: no-cache”的话,浏览器将缓存响应并不会重新提交请求。可以添加像时间戳或一个随机数的不同GET请求参数(参考 bypassing the cache)。

注意:如果httpRequest变量是全局的,makeRequest()方法因为冲突可能会被重写。将httpRequest变量定义在一个闭包中的话,可以避免AJAX函数的冲突。

注意:如果出现通信错误(如服务器端被关闭),当试图访问状态字段时在onreadystatechange的方法中将会抛出一个异常。确保if语句声明在try..catch语句中。

function alertContents() {

try {

if (httpRequest.readyState === 4) {

if (httpRequest.status === 200) {

alert(httpRequest.responseText);

} else {

alert('There was a problem with the request.');

       }

   }

 }

catch( e ) {

alert('Caught Exception: ' + e.description);

   }

}

第四步:使用XML进行响应

       在前面的例子中,当接收到响应后使用XMLHttpRequest对象的responseText属性访问“test.html”文件包含的内容。现在尝试一下responseXML属性。

首先,创建一个用于请求的名为“test.xml”的有效XML文档,代码如下:


I'm a test.

在脚本中,只需要修改请求行:

onclick="makeRequest('test.xml')">

然后在alertContents()方法中,需要使用如下代码替换alert(httpRequest.responseText);这一行代码:

var xmldoc = httpRequest.responseXML;

var root_node = xmldoc.getElementsByTagName('root').item(0);

alert(root_node.firstChild.data);

这段代码需要由responseXML给予的XMLDocument对象,然后使用DOM方法来访问XML文档中的数据。

第五步:处理数据

       最后,向服务器端发送一些数据并接收响应。这次JavaScript脚本请求一个动态页面“test.php”,该页面将根据发送的数据返回一个“computedString”-“Hello, [user data]!”,并使用alert()方法进行打印。

首先,向HTML页面中添加一个文本框,用户可以通过该文本框输入他们的名字:

Your name:

Make a request

还需要添加一行事件处理器用于从文本框获取用户的数据,并将该数据随着URL传递给makeRequest()方法:

document.getElementById("ajaxButton").onclick = function() {

var userName = document.getElementById("ajaxTextbox").value;

makeRequest('test.php',userName);

};

修改makeRequest()方法用于接收用户数据并发送给服务器端。将请求方式从GET修改为POST,用户数据作为参数传递给httpRequest.send()方法:

function makeRequest(url, userName) {

...

httpRequest.onreadystatechange = alertContents;

httpRequest.open('POST', url);

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

httpRequest.send('userName=' + encodeURIComponent(userName));

}

alertContents()方法可以向第三步一样利用alert()方法打印服务器端返回的数据。假设服务器端返回的是computedString和用户数据的话,如果用户在文本框中输入“Jane”服务器端响应的内容会像是这样:

{“userData”:”Jane”,”computedString”:”Hi, Jane!”}

在alertContents()方法中使用这些数据,不仅可以使用alert()方法打印responseText的内容,还可以将其解析并打印computedString属性内容:

function alertContents() {

if (httpRequest.readyState === 4) {

if (httpRequest.status === 200) {

var response = JSON.parse(httpRequest.responseText);

alert(response.computedString);

} else {

alert('There was a problem with the request.');

}

}

}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容