你的位置:首页 > Java教程

[Java教程]Ajax我选择这样入门


什么是AJAX?

AJAX的意思就是异步的JavaScript和

可以考虑的两个特性:

  • 向服务器端发送请求,而不用重新加载页面。
  • 从服务器端接收数据并处理。

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

需要通过

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

1
2
3
4
5
6
var httpRequest;
if (window.// Mozilla, Safari, IE7+ ...
httpRequest = new } else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.}

注意:出于演示目的,上面创建

接下来,当接收到服务器端响应时,需要告诉HTTP请求对象使用JavaScript函数来处理响应。将

1
httpRequest.onreadystatechange = nameOfTheFunction;

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

1
2
3
httpRequest.onreadystatechange = function(){
// process the server response
};

在处理完服务器端的响应之后,我们就可以调用

1
2
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时,向服务器端发送请求的数据内容。如果发送的是表单数据格式的话,服务器端可以向字符串一样地解析。

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

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

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

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

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

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

1
httpRequest.onreadystatechange = nameOfTheFunction;

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

1
2
3
4
5
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调用是否是成功的。

1
2
3
4
5
6
7
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.response

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

第三步:一个简单的例子

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
Make a request
</span>
<script type="text/javascript">
(function() {
var httpRequest;
document.getElementById("ajaxButton").onclick = function() { makeRequest('test.html'); };

function makeRequest(url) {
if (window.// Mozilla, Safari, ...
httpRequest = new } else if (window.ActiveXObject) { // IE
try {
httpRequest = new ActiveXObject("Ms }
catch (e) {
try {
httpRequest = new ActiveXObject("Microsoft. }
catch (e) {}
}
}

if (!httpRequest) {
alert('Giving up :( Cannot create an 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.');
}
}
}
})();
</script>

在这个例子中:

  • 在浏览器中用户单击“Make a request”链接;
  • 事件处理器调用makeRequest()方法,通过向该函数传递的参数,请求一个处在同一目录中的“test.html”HTML文件;
  • 请求后,(onreadystatechange)执行 alertContents()方法;
  • alertContents()方法用于检查如果正确地接收到响应,利用alert()方法打印“test.html”文件包含的内容。

注意:如果你发送一个请求后返回的是一段

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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);
}
}

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

1
2
3
var var root_node = 'root').item(0);
alert(root_node.firstChild.data);

这段代码需要由response

第五步:处理数据

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

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

1
2
3
4
5
6
<label>Your name: 
<input type="text" id="ajaxTextbox" />
</label>
<span id="ajaxButton" style="cursor: pointer; text-decoration: underline">
Make a request
</span>

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

1
2
3
4
document.getElementById("ajaxButton").onclick = function() { 
var userName = document.getElementById("ajaxTextbox").value;
makeRequest('test.php',userName);
};

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

1
2
3
4
5
6
7
8
9
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属性内容:

1
2
3
4
5
6
7
8
9
10
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.');
}
}
}