1. 响应数据格式(数据协议)
服务端应该设置一个合理的Content-Type。
(1)XML:一种数据描述手段,因数据冗余太多被淘汰。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open('GET', 'xml.php');
xhr.send();
xhr.onreadystatechange = function() {
if(this.readyState != 4) return;
// XML数据操作类似于DOM方式
console.log(this.responseXML.documentElement.getElementsByTagName('name')[0]); // <name>Karry</name>
console.log(this.responseXML.documentElement.children[0].innerHTML); // Karry
}
</script>
</head>
<body>
</body>
</html>
xml.php
<?php
header('Content-Type: application/xml');
?>
<?xml version='1.1' encoding="utf-8"?>
<person>
<name>Karry</name>
<age>21</age>
<gender>man</gender>
</person>
(2)JSON:一种数据描述手段,类似于JavaScript字面量方式,服务端采用JSON格式返回数据,客户端按照JSON格式解析数据。
(3)处理响应数据渲染:模板引擎art-template,https://aui.github.io/art-template/,实际上就是一个API,目的是为了可以更容易的将数据渲染到HTML中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<table id="demo"></table>
<script src="template-web.js"></script>
<script id="tmpl" type="text/x-art-template">
{{each comments}}
<tr>
<td>{{$index}}</td>
<td>{{$value.name}}</td>
<td>{{$value.age}}</td>
</tr>
{{/each}}
</script>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'users.php');
xhr.send();
xhr.onreadystatechange = function() {
if(this.readyState != 4)return;
var res = JSON.parse(this.responseText);
console.log(res);
// 使用模板引擎的API渲染数据
var context = {comments: res}; //
console.log(context);
var html = template('tmpl', context);
console.log(html);
document.getElementById('demo').innerHTML = html;
}
</script>
</body>
</html>
(4)兼容方案:XMLHttpRequest在老版本浏览器(IE5/6)中由兼容问题,可以通过另一种方式代替。
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHttp');
2. 封装
难点:get、post请求类型及字母大小写的处理,url是否带参数,数据格式是否需在请求头中设置,以对象为参数如何处理,封装函数的返回值(委托/回调)。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script>
function ajax(method, url, params, done) {
method = method.toUpperCase();
var xhr = new XMLHttpRequest();
if(typeof params == 'object') { // 以对象方式传递参数
var arr = [];
for(var key in params) {
var value = params[key];
arr.push(key + '=' + value);
}
params = arr.join('&');
}
if(method == 'GET') {
url += '?' + params;
}
xhr.open(method, url);
var data = null;
if(method == 'POST') {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
data = params;
}
xhr.send(data);
xhr.onreadystatechange = function() {
if(this.readyState != 4)return;
done(this.responseText);
}
}
var onDone = function(res) {
console.log('hahaha');
console.log(res);
console.log('做完了');
}
ajax('GET', 'users.php', 'id=1', onDone);
ajax('GET', 'users.php', {id: 1}, onDone);
ajax('POST', 'add.php', 'key1=value1&key2=value2', onDone);
ajax('POST', 'add.php', {key1: 'value1', key2: 'value2'}, onDone);
</script>
</head>
<body>
</body>
</html>
回调补充
<script>
console.log('1');
ajax('time.php', function(res){
console.log('3');
ajax('time.php', function(res){
})
console.log('4');
})
console.log('2');
ajax('time.php')
.then(function(res){
return ajax('time.php');
})
.then(function(res){
return ajax('time.php');
})
</script>