AJAX使用手册

本文最后更新于:3 年前

AJAX(Asynchronous JavaScript And XML)

AJAX不是JavaScript的规范,它只是Asynchronous JavaScript and XML的缩写,意思就是用==JavaScript执行异步网络请求==。

AJAX 是开发者的梦想,因为您能够:

  • 不刷新页面更新网页
  • 在页面加载后从服务器请求数据
  • 在页面加载后从服务器接收数据
  • 在后台向服务器发送数据

AJAX 并非编程语言。

AJAX 仅仅组合了:

  • 浏览器内建的 XMLHttpRequest 对象(从 web 服务器请求数据)
  • JavaScript 和 HTML DOM(显示或使用数据)

Ajax 是一个令人误导的名称。Ajax 应用程序可能使用 XML 来传输数据,但将数据作为纯文本或 JSON 文本传输也同样常见。

Ajax 允许通过与场景后面的 Web 服务器交换数据来异步更新网页。这意味着可以更新网页的部分,而不需要重新加载整个页面。

XMLHttpRequest

在现代浏览器上写AJAX主要依靠XMLHttpRequest对象:

实例

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
function success(text) {
var textarea = document.getElementById('test-ie-response-text');
textarea.value = text;
}

function fail(code) {
var textarea = document.getElementById('test-ie-response-text');
textarea.value = 'Error code: ' + code;
}

var request = new ActiveXObject('Microsoft.XMLHTTP'); // 新建Microsoft.XMLHTTP对象

request.onreadystatechange = function () { // 状态发生变化时,函数被回调
if (request.readyState === 4) { // 成功完成
// 判断响应结果:
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
return success(request.responseText);
} else {
// 失败,根据响应码判断失败原因:
return fail(request.status);
}
} else {
// HTTP请求还在继续...
}
}

// 发送请求:
request.open('GET', '/api/categories');//参数一:指定GET或者PST方法;参数二:指定URL地址
//request.open('GET', '/api/categories',true);//参数三:指定是否需要使用异步,默认true,可以不写
request.send();

alert('请求已发送,请等待响应...');

XMLHttpRequest对象的open()方法有3个参数,第一个参数指定是GET还是POST,第二个参数指定URL地址,第三个参数指定是否使用异步,默认是true,所以不用写。

注意,千万不要把第三个参数指定为false,否则浏览器将停止响应,直到AJAX请求完成。如果这个请求耗时10秒,那么10秒内你会发现浏览器处于“假死”状态。

最后调用send()方法才真正发送请求。GET请求不需要参数,POST请求需要把body部分以字符串或者FormData对象传进去。

通用写法

如果你想把标准写法和IE(低版本的IE)写法混在一起,可以这么写:

1
2
3
4
5
6
var request;
if (window.XMLHttpRequest) {
request = new XMLHttpRequest();
} else {
request = new ActiveXObject('Microsoft.XMLHTTP');
}

通过检测window对象是否有XMLHttpRequest属性来确定浏览器是否支持标准的XMLHttpRequest

注意,不要根据浏览器的navigator.userAgent来检测浏览器是否支持某个JavaScript特性,一是因为这个字符串本身可以伪造,二是通过IE版本判断JavaScript特性将非常复杂。

当创建了XMLHttpRequest对象后,要先设置onreadystatechange的回调函数。在回调函数中,通常我们只需通过readyState === 4判断请求是否完成,如果已完成,再根据status === 200判断是否是一个成功的响应。

安全限制

上面代码的URL使用的是相对路径。如果你把它改为'http://www.sina.com.cn/',再运行,肯定报错。这是由于跨域问题,关于跨域问题的服务端解决方案,请参考一步解决CORS(跨域)问题

前端的解决方法有JSONP,他有个限制,及只能通过Get 请求,并且要求返回JavaScript。这种方式跨域实际上是利用了浏览器允许跨域引用JavaScript资源。

1
2
3
4
5
6
7
8
9
<html>
<head>
<script src="http://example.com/abc.js"></script>
...
</head>
<body>
...
</body>
</html>

JSONP通常以函数调用的形式返回,例如,返回JavaScript内容如下:

1
foo('data');

这样一来,我们如果在页面中先准备好foo()函数,然后给页面动态加一个<script>节点,相当于动态读取外域的JavaScript资源,最后就等着接收回调了。

以163的股票查询URL为例,对于URL:http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice,你将得到如下返回:

1
refreshPrice({"0000001":{"code": "0000001", ... });

因此我们需要首先在页面中准备好回调函数:

1
2
3
4
5
6
7
8
function refreshPrice(data) {
var p = document.getElementById('test-jsonp');
p.innerHTML = '当前价格:' +
data['0000001'].name +': ' +
data['0000001'].price + ';' +
data['1399001'].name + ': ' +
data['1399001'].price;
}

最后用getPrice()函数触发:

1
2
3
4
5
6
7
function getPrice() {
var
js = document.createElement('script'),
head = document.getElementsByTagName('head')[0];
js.src = 'http://api.money.126.net/data/feed/0000001,1399001?callback=refreshPrice';
head.appendChild(js);
}

就完成了跨域加载数据。

CORS

原理见一步解决CORS(跨域)问题


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!