AJAX实现JSON与XML数据交换详解
一、AJAX基础概念
AJAX(Asynchronous JavaScript and XML)是一种无需重新加载整个网页的情况下,能够更新部分网页的技术。
二、JSON数据交换
1. 发送JSON数据到服务器
// 创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
// 配置请求
xhr.open('POST', 'https://api.example.com/data', true);
xhr.setRequestHeader('Content-Type', 'application/json');
// 准备JSON数据
var data = {
name: "张三",
age: 25,
email: "zhangsan@example.com"
};
// 发送请求
xhr.send(JSON.stringify(data));
// 处理响应
xhr.onload = function() {
if (xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
};
2. 使用Fetch API发送JSON(现代方法)
// 发送JSON数据
fetch('https://api.example.com/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: "李四",
age: 30
})
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
3. 接收JSON响应
// 获取JSON数据
function getJSONData() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data.json', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
var jsonData = JSON.parse(xhr.responseText);
processJSONData(jsonData);
}
};
xhr.send();
}
// 处理JSON数据
function processJSONData(data) {
// 示例:显示用户列表
var userList = document.getElementById('user-list');
data.users.forEach(function(user) {
var li = document.createElement('li');
li.textContent = user.name + ' - ' + user.email;
userList.appendChild(li);
});
}
三、XML数据交换
1. 发送XML数据
// 创建XML文档
function createXMLData() {
var xmlDoc = document.implementation.createDocument("", "", null);
var root = xmlDoc.createElement("person");
var name = xmlDoc.createElement("name");
name.textContent = "王五";
var age = xmlDoc.createElement("age");
age.textContent = "28";
root.appendChild(name);
root.appendChild(age);
xmlDoc.appendChild(root);
return xmlDoc;
}
// 发送XML请求
function sendXMLData() {
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/xml-endpoint', true);
var xmlData = createXMLData();
var serializer = new XMLSerializer();
var xmlString = serializer.serializeToString(xmlData);
xhr.setRequestHeader('Content-Type', 'application/xml');
xhr.onload = function() {
if (xhr.status === 200) {
// 解析XML响应
var parser = new DOMParser();
var responseXML = parser.parseFromString(xhr.responseText, "application/xml");
processXMLResponse(responseXML);
}
};
xhr.send(xmlString);
}
2. 接收和解析XML响应
// 获取XML数据
function getXMLData() {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data.xml', true);
xhr.responseType = "document"; // 指定响应类型为XML文档
xhr.onload = function() {
if (xhr.status === 200) {
var xmlDoc = xhr.responseXML;
parseXMLData(xmlDoc);
}
};
xhr.send();
}
// 解析XML数据
function parseXMLData(xmlDoc) {
var persons = xmlDoc.getElementsByTagName("person");
var resultDiv = document.getElementById('result');
for (var i = 0; i < persons.length; i++) {
var name = persons[i].getElementsByTagName("name")[0].textContent;
var age = persons[i].getElementsByTagName("age")[0].textContent;
var p = document.createElement('p');
p.textContent = "姓名: " + name + ", 年龄: " + age;
resultDiv.appendChild(p);
}
}
四、对比JSON与XML
1. JSON优点:
- 更轻量,文件大小更小
- 解析更快(使用内置JSON.parse)
- 更易读和编写
- 直接映射到JavaScript对象
2. XML优点:
- 支持注释
- 支持命名空间
- 支持更复杂的数据结构
- 支持模式验证(XSD)
五、封装通用AJAX函数
// 通用的AJAX请求函数
function ajaxRequest(config) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(config.method || 'GET', config.url, true);
// 设置请求头
if (config.headers) {
for (var header in config.headers) {
xhr.setRequestHeader(header, config.headers[header]);
}
}
// 设置响应类型
if (config.responseType) {
xhr.responseType = config.responseType;
}
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
var response = xhr.response;
// 根据Content-Type自动解析
var contentType = xhr.getResponseHeader('Content-Type');
if (contentType && contentType.includes('application/json')) {
response = JSON.parse(xhr.responseText);
} else if (contentType && contentType.includes('application/xml')) {
var parser = new DOMParser();
response = parser.parseFromString(xhr.responseText, "application/xml");
}
resolve(response);
} else {
reject(new Error('Request failed with status: ' + xhr.status));
}
};
xhr.onerror = function() {
reject(new Error('Network error'));
};
// 发送数据
if (config.data) {
if (typeof config.data === 'object' && config.data.constructor !== FormData) {
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(config.data));
} else {
xhr.send(config.data);
}
} else {
xhr.send();
}
});
}
// 使用示例
ajaxRequest({
url: 'https://api.example.com/data',
method: 'POST',
headers: {
'Authorization': 'Bearer token123'
},
data: { name: '张三', age: 25 }
})
.then(function(data) {
console.log('Success:', data);
})
.catch(function(error) {
console.error('Error:', error);
});
六、实际应用示例
1. 结合表单提交JSON
<form id="user-form">
<input type="text" id="username" placeholder="用户名">
<input type="email" id="email" placeholder="邮箱">
<button type="submit">提交</button>
</form>
<script>
document.getElementById('user-form').addEventListener('submit', function(e) {
e.preventDefault();
var userData = {
username: document.getElementById('username').value,
email: document.getElementById('email').value
};
fetch('/api/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(userData)
})
.then(response => response.json())
.then(data => {
alert('提交成功: ' + data.message);
})
.catch(error => {
console.error('Error:', error);
});
});
</script>
2. 从XML API获取数据并显示
// 从XML API获取天气数据
function getWeatherData(city) {
var xhr = new XMLHttpRequest();
var url = 'https://api.weather.com/data/2.5/weather?q=' +
encodeURIComponent(city) + '&mode=xml&units=metric';
xhr.open('GET', url, true);
xhr.onload = function() {
if (xhr.status === 200) {
var parser = new DOMParser();
var xmlDoc = parser.parseFromString(xhr.responseText, "text/xml");
var temperature = xmlDoc.getElementsByTagName("temperature")[0]
.getAttribute("value");
var weather = xmlDoc.getElementsByTagName("weather")[0]
.getAttribute("value");
document.getElementById('weather-result').innerHTML =
'温度: ' + temperature + '°C, 天气: ' + weather;
}
};
xhr.send();
}
七、最佳实践建议
错误处理:始终添加错误处理逻辑
超时设置:为长时间请求设置超时
安全性:验证和清理所有输入数据
性能优化:使用适当的缓存策略
兼容性:考虑旧浏览器支持
异步处理:使用async/await或Promise处理异步操作
八、现代替代方案
// 使用Axios库(推荐)
axios.post('/api/data', {
firstName: '张',
lastName: '三'
})
.then(function (response) {
console.log(response.data);
})
.catch(function (error) {
console.error(error);
});
// 使用jQuery AJAX
$.ajax({
url: '/api/data',
type: 'POST',
dataType: 'json',
data: JSON.stringify({name: '李四'}),
contentType: 'application/json',
success: function(data) {
console.log(data);
}
});
这些方法提供了灵活的数据交换方案,可以根据具体需求选择JSON或XML格式。在大多数现代Web应用中,JSON由于其轻量和易用性而更受欢迎。