Skip to content

AJAX XML

PHP 示例 - 使用服务器数据 (JSON) 的 AJAX

Section titled “PHP 示例 - 使用服务器数据 (JSON) 的 AJAX”

AJAX(Asynchronous JavaScript and XML,异步 JavaScript 和 XML)允许网页通过在后台与服务器交换数据来动态更新内容,而无需完全重新加载页面。虽然最初与 XML 相关,但 JSON(JavaScript Object Notation,JavaScript 对象表示法)现在已成为 AJAX 通信的主要数据格式,因为它更简单且能直接映射到 JavaScript 对象。

本示例演示了网页如何使用 JavaScript 的 fetch API 从 PHP 脚本请求数据,该脚本接着读取信息(最初来自 XML 文件,但以 JSON 格式提供)并将其发回页面。

设想一个艺术家下拉列表。选择一个艺术家会触发一个 AJAX 请求到 PHP 脚本,该脚本会查找该艺术家的 CD 详细信息(来自 cd_catalog.xml 等数据源)并将信息以 JSON 格式返回。然后 JavaScript 在页面上显示这些信息。

**CD info will be listed here...**

示例说明 - HTML 和 JavaScript(客户端)

Section titled “示例说明 - HTML 和 JavaScript(客户端)”

HTML 设置了一个带有下拉列表(<select>) 的简单表单。使用 JavaScript 为此下拉列表附加了一个事件监听器。

<form id="cdForm">
<label for="cdSelect">Select a CD Artist:</label>
<select name="cds" id="cdSelect">
<option value="">Select an Artist...</option>
<option value="Bob Dylan">Bob Dylan</option>
<option value="Bee Gees">Bee Gees</option>
<option value="Cat Stevens">Cat Stevens</option>
</select>
</form>
<div id="txtHint" style="margin-top: 10px;">
**CD info will be listed here...**
</div>

当用户更改选定的选项时:

  1. 一个事件监听器触发 showCD() 函数,并传入选定艺术家的姓名。
  2. showCD() 函数(使用 async/await 实现更清晰的异步代码):
  3. 检查是否已选择艺术家。如果未选择,则重置显示区域(txtHint)。
  4. 显示“加载中…”消息,以提供更好的用户体验。
  5. 使用 fetch() API 向 get_cd_data.php 发送异步 GET 请求。
  6. 艺术家姓名经过 URL 编码并作为查询参数附加(?artist=...)。
  7. 检查 HTTP 响应状态是否为 OK(例如 200)。如果不 OK,则抛出错误。
  8. 使用 response.json() 将响应体解析为 JSON。
  9. 检查解析后的 JSON 数据是否存在应用程序错误或有效的 CD 信息。
  10. 使用接收到的数据(或错误消息)更新 txtHint 元素的 HTML。
  11. 包含 try...catch 来处理潜在的网络错误或 JSON 解析问题。
document.getElementById('cdSelect').addEventListener('change', function() {
showCD(this.value);
});
async function showCD(artistName) {
const hintElement = document.getElementById("txtHint");
if (artistName === "") { /* ... 重置 ... */ return; }
hintElement.innerHTML = "<i>Loading...</i>";
try {
const response = await fetch(`get_cd_data.php?artist=${encodeURIComponent(artistName)}`);
if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); }
const data = await response.json();
if (data.error) {
hintElement.innerHTML = `<span style='color: red;'>Error: ${data.error}</span>`;
} else if (data.title) {
// ... 从数据对象显示 CD 信息 ...
hintElement.innerHTML = `**Title:** ${data.title} ...`;
} else {
hintElement.innerHTML = "<i>No CD found.</i>";
}
} catch (error) {
console.error('Fetch error:', error);
hintElement.innerHTML = `<span style='color: red;'>Failed to fetch data.</span>`;
}
}

PHP 文件(get_cd_data.php - 服务器端)

Section titled “PHP 文件(get_cd_data.php - 服务器端)”

此 PHP 脚本在服务器上运行。它接收 JavaScript 请求的艺术家姓名,查找相应的 CD 数据(在本例中,通过解析 XML 文件),并将数据以 JSON 响应格式发回。

数据源(cd_catalog.xml - 假定结构):

Section titled “数据源(cd_catalog.xml - 假定结构):”
<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Still Waters</TITLE>
<ARTIST>Bee Gees</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>Polydor</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1997</YEAR>
</CD>
<!-- ... 更多 CD 条目 ... -->
</CATALOG>
  1. 设置 Content-Type 头信息为 application/json,通知客户端返回的是 JSON 数据。
  2. 从 $_GET['artist'] 查询参数中检索艺术家姓名。在实际应用中,如有必要请对输入进行清理或验证。
  3. 定义 XML 数据文件的路径。
  4. 使用 libxml 错误处理并禁用外部实体以提高安全性。
  5. 使用 simplexml_load_file() 加载 XML 文件。处理潜在的加载错误。
  6. 使用 XPath($xml->xpath(...))高效地搜索匹配请求艺术家的 CD 元素。与手动遍历所有元素相比,XPath 通常效率更高。
  7. 如果找到匹配的 CD:
  8. 从 SimpleXMLElement 中提取所需数据(标题、艺术家、国家/地区等)。
  9. 创建一个包含 CD 数据的 PHP 关联数组。
  10. 如果未找到匹配项或发生错误:
  11. 创建一个包含错误消息的关联数组。
  12. 使用 json_encode() 将 PHP 数组转换为 JSON 字符串。
  13. 输出 JSON 字符串作为响应体。
<?php
// 设置头信息以指示 JSON 响应
header('Content-Type: application/json');
// 从请求中获取 artist 参数
$requested_artist = isset($_GET['artist']) ? trim($_GET['artist']) : '';
$xmlFile = 'cd_catalog.xml'; // XML 文件路径
$response_data = []; // 初始化响应数组
if (empty($requested_artist)) {
$response_data['error'] = 'No artist specified.';
} elseif (!file_exists($xmlFile)) {
$response_data['error'] = 'Data source not found.';
} else {
// 启用 libxml 错误处理并禁用外部实体(安全)
libxml_use_internal_errors(true);
libxml_disable_entity_loader(true);
$xml = simplexml_load_file($xmlFile);
if ($xml === false) {
$response_data['error'] = 'Failed to parse XML data.';
// (可选)在此处记录 libxml_get_errors() 进行调试
libxml_clear_errors();
} else {
// 使用 XPath 按艺术家查找 CD
// 注意:如果未仔细处理 $requested_artist,则可能存在 XPath 注入。
// 在实际应用程序中,在使用 XPath 之前请验证/清理 $requested_artist。
// 如果查询数据库,使用预处理语句通常更安全。
$query = sprintf("//CD[ARTIST='%s']", addslashes($requested_artist)); // XPath 的基本转义
$results = $xml->xpath($query);
if ($results && count($results) > 0) {
// 找到至少一个匹配项,取第一个
$cd = $results[0];
$response_data = [
'title' => (string)$cd->TITLE, // 将 SimpleXMLElements 转换为字符串
'artist' => (string)$cd->ARTIST,
'country' => (string)$cd->COUNTRY,
'company' => (string)$cd->COMPANY,
'price' => (string)$cd->PRICE,
'year' => (string)$cd->YEAR
];
} else {
// 未找到该艺术家的 CD
$response_data['message'] = 'No CD found for this artist.';
// 没有错误,只是没有找到数据
}
}
}
// 将响应数组编码为 JSON 并输出
echo json_encode($response_data);
?>

这种更新的方法使用了现代 JavaScript (fetch、async/await),使用标准的 JSON 格式进行通信,并在服务器端采用了更高效的 XML 解析(XPath),反映了当前的 Web 开发实践。