AJAX ASP/PHP 实例
AJAX ASP/PHP 实例(中文讲解)
本教程展示如何使用 AJAX 与服务器端技术(ASP 和 PHP)交互,结合 JSON 数据格式,实现在客户端动态加载和提交数据。实例将使用 Node.js 模拟类似 ASP/PHP 的后端(因现代开发中 ASP/PHP 较少使用,且 Node.js 更易于演示),并提供等效的 PHP 代码。示例包括查询用户(GET 请求)和添加用户(POST 请求),使用 XMLHttpRequest
和 fetch
,结合 MongoDB 存储数据。内容简洁清晰,适合理解 AJAX 与服务器端的交互。
1. 实例概述
- 目标:通过 AJAX 实现用户管理功能:
- GET 请求:查询 MongoDB 中的用户列表,显示在页面。
- POST 请求:提交新用户数据到服务器,存入 MongoDB。
- 技术栈:
- 客户端:HTML + JavaScript(
XMLHttpRequest
和fetch
)。 - 服务器:Node.js(Express)模拟 ASP/PHP 后端,另提供 PHP 等效代码。
- 数据库:MongoDB,存储 JSON 格式数据。
- 数据格式:JSON,用于前后端交互。
2. 环境准备
确保以下工具已安装:
- Node.js:LTS 版本(如 v20.x),运行
node -v
检查。 - MongoDB:本地运行或使用 MongoDB Atlas。
- PHP(可选):如果运行 PHP 示例,需 PHP 7.4+ 和 MongoDB PHP 驱动。
- npm 依赖(Node.js 示例):Express 和 MongoDB 驱动。
安装 Node.js 依赖:
mkdir ajax-example
cd ajax-example
npm init -y
npm install express mongodb
PHP 环境(可选):
- 安装 PHP 和 MongoDB 驱动:
pecl install mongodb
- 编辑
php.ini
,添加extension=mongodb.so
。
3. Node.js 后端(模拟 ASP/PHP)
以下是 Node.js + Express 的后端代码,模拟 ASP/PHP 的 RESTful API 功能。
3.1 服务器代码(server.js)
const express = require('express');
const { MongoClient } = require('mongodb');
const app = express();
const uri = 'mongodb://localhost:27017/myDatabase';
const client = new MongoClient(uri);
app.use(express.json());
app.use(express.static('public'));
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST');
next();
});
// 查询用户
app.get('/users', async (req, res) => {
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('users');
const users = await collection.find({}).toArray();
res.json(users);
} catch (error) {
console.error('查询失败:', error);
res.status(500).json({ error: '服务器错误' });
} finally {
await client.close();
}
});
// 添加用户
app.post('/users', async (req, res) => {
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('users');
const user = req.body;
const result = await collection.insertOne(user);
res.json({ message: '添加成功', id: result.insertedId });
} catch (error) {
console.error('添加失败:', error);
res.status(500).json({ error: '服务器错误' });
} finally {
await client.close();
}
});
app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));
- 说明:
/users
(GET):返回用户列表(JSON)。/users
(POST):接收 JSON 数据,插入新用户。- CORS 允许跨域请求。
- 模拟 ASP/PHP 的 RESTful API 行为。
4. PHP 后端(等效实现)
以下是等效的 PHP 代码,使用 MongoDB 驱动,需运行在 PHP 服务器(如 Apache/Nginx)。
4.1 PHP 代码(api.php)
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');
require 'vendor/autoload.php'; // 需安装 mongodb/mongodb 库
use MongoDB\Client;
$uri = 'mongodb://localhost:27017';
$client = new Client($uri);
$collection = $client->myDatabase->users;
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
try {
$users = $collection->find()->toArray();
// 转换为标准 JSON 对象
$users = array_map(function($user) {
$user['_id'] = (string)$user['_id']; // ObjectId 转为字符串
return $user;
}, $users);
echo json_encode($users);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => '服务器错误']);
}
} elseif ($method === 'POST') {
try {
$data = json_decode(file_get_contents('php://input'), true);
if (!$data || !isset($data['name']) || !isset($data['age'])) {
http_response_code(400);
echo json_encode(['error' => '无效数据']);
exit;
}
$result = $collection->insertOne($data);
echo json_encode(['message' => '添加成功', 'id' => (string)$result->getInsertedId()]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => '服务器错误']);
}
} else {
http_response_code(405);
echo json_encode(['error' => '方法不支持']);
}
?>
- 说明:
- 使用 MongoDB PHP 驱动(需安装
mongodb/mongodb
)。 - GET 请求返回用户列表,POST 请求添加用户。
- 输出 JSON,处理 MongoDB 的
_id
(ObjectId 转为字符串)。 - 配置 CORS 允许跨域。
运行 PHP:
- 将
api.php
放入 Web 服务器(如 Apache)的htdocs
目录。 - 访问
http://localhost/api.php
。
5. 客户端代码(AJAX)
以下是客户端 HTML,使用 XMLHttpRequest
和 fetch
发送 AJAX 请求,处理 JSON 响应。
5.1 客户端(public/index.html)
<!DOCTYPE html>
<html>
<head>
<title>AJAX ASP/PHP 示例</title>
<style>
pre { font-size: 16px; background: #f4f4f4; padding: 10px; }
button, input { padding: 10px; margin: 5px; }
</style>
</head>
<body>
<h1>用户管理</h1>
<div>
<input id="name" placeholder="姓名">
<input id="age" type="number" placeholder="年龄">
<button onclick="addUser()">添加用户(XMLHttpRequest)</button>
<button onclick="addUserFetch()">添加用户(Fetch)</button>
</div>
<button onclick="loadUsers()">加载用户</button>
<pre id="result">点击按钮加载用户数据...</pre>
<script>
// XMLHttpRequest 加载用户
function loadUsers() {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/users', true); // 替换为 PHP 的 URL(如 http://localhost/api.php)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const users = JSON.parse(xhr.responseText);
document.getElementById('result').innerText = JSON.stringify(users, null, 2);
} catch (error) {
document.getElementById('result').innerText = '错误:JSON 解析失败';
}
} else {
document.getElementById('result').innerText = `错误:${xhr.statusText} (${xhr.status})`;
}
}
};
xhr.onerror = function () {
document.getElementById('result').innerText = '错误:网络错误';
};
xhr.send();
}
// XMLHttpRequest 添加用户
function addUser() {
const name = document.getElementById('name').value;
const age = parseInt(document.getElementById('age').value);
if (!name || !age) {
alert('请输入姓名和年龄');
return;
}
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/users', true); // 替换为 PHP 的 URL
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
alert(response.message);
loadUsers();
} catch (error) {
alert('错误:JSON 解析失败');
}
} else {
alert(`添加失败:${xhr.statusText}`);
}
}
};
xhr.onerror = function () {
alert('网络错误');
};
xhr.send(JSON.stringify({ name, age, hobbies: ['未知'] }));
}
// Fetch 添加用户
async function addUserFetch() {
const name = document.getElementById('name').value;
const age = parseInt(document.getElementById('age').value);
if (!name || !age) {
alert('请输入姓名和年龄');
return;
}
try {
const response = await fetch('http://localhost:3000/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, age, hobbies: ['未知'] })
});
if (!response.ok) throw new Error(`服务器错误:${response.status}`);
const result = await response.json();
alert(result.message);
loadUsers();
} catch (error) {
alert(`添加失败:${error.message}`);
}
}
</script>
</body>
</html>
- 说明:
- 使用
XMLHttpRequest
和fetch
发送 GET/POST 请求。 - 处理 JSON 响应,显示用户列表或添加结果。
- URL 可替换为 PHP 的端点(如
http://localhost/api.php
)。
6. MongoDB 数据准备
在 MongoDB 中插入测试数据:
use myDatabase
db.users.insertMany([
{ name: "张三", age: 25, hobbies: ["读书", "旅行"] },
{ name: "李四", age: 30, hobbies: ["编程", "运动"] }
])
7. 运行和测试
7.1 Node.js 后端
- 启动服务器:
node server.js
- 访问客户端:
- 打开浏览器,访问
http://localhost:3000
。 - 点击“加载用户”,显示用户列表。
- 输入姓名和年龄,点击“添加用户(XMLHttpRequest)”或“添加用户(Fetch)”,添加用户并刷新列表。
7.2 PHP 后端
- 部署 PHP:
- 将
api.php
放入 Web 服务器的根目录(如 Apache 的htdocs
)。 - 确保 MongoDB PHP 驱动已安装。
- 修改客户端 URL:
- 在
index.html
中,将 AJAX 请求的 URL 改为http://localhost/api.php
。
- 访问:
- 访问
http://localhost/index.html
(需通过 Web 服务器)。 - 测试功能与 Node.js 版本相同。
7.3 响应示例
- GET /users:
[
{
"_id": "someObjectId1",
"name": "张三",
"age": 25,
"hobbies": ["读书", "旅行"]
},
{
"_id": "someObjectId2",
"name": "李四",
"age": 30,
"hobbies": ["编程", "运动"]
}
]
- POST /users:
{
"message": "添加成功",
"id": "someObjectId3"
}
8. JSON 在实例中的作用
- 客户端:
POST
请求:使用JSON.stringify()
将数据转为 JSON 字符串。GET
响应:使用JSON.parse()
(XMLHttpRequest)或response.json()
(fetch)解析 JSON。- 服务器:
- Node.js:
res.json()
自动调用JSON.stringify()
。 - PHP:
json_encode()
生成 JSON 响应。 - MongoDB:存储 JSON 格式数据,查询结果直接转为 JSON。
9. ASP 等效说明
经典 ASP(Active Server Pages)使用 VBScript 或 JScript,结合 ADO 访问数据库。由于 ASP 已较少使用,且 MongoDB 驱动支持有限,这里简述等效逻辑:
- ASP 等效伪代码(GET /users):
<%@ Language="VBScript" %>
<%
Response.ContentType = "application/json"
Response.AddHeader "Access-Control-Allow-Origin", "*"
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "MongoDB connection string" ' 假设支持 MongoDB
Set rs = conn.Execute("SELECT * FROM users") ' 模拟查询
Dim users
users = "["
Do While Not rs.EOF
users = users & "{""name"": """ & rs("name") & """, ""age"": " & rs("age") & "},"
rs.MoveNext
Loop
users = Left(users, Len(users)-1) & "]"
Response.Write users
rs.Close
conn.Close
%>
- 说明:
- ASP 通常使用 ADO 访问 SQL Server 或其他数据库,MongoDB 需第三方驱动。
- 输出 JSON 字符串,需手动构造。
- 现代开发推荐 Node.js 或 PHP,因 ASP 生态较老旧。
10. 注意事项与最佳实践
- 跨域处理:
- 本例使用 CORS(
Access-Control-Allow-Origin: *
)。 - 生产环境限制域名:
javascript res.header('Access-Control-Allow-Origin', 'http://trusted-domain.com');
- 错误处理:
XMLHttpRequest
:检查xhr.status
和onerror
。fetch
:检查response.ok
和try-catch
。- 服务器返回明确错误(如
{ error: '服务器错误' }
)。
- JSON 安全:
- 客户端:用
try-catch
包裹JSON.parse()
。 - 服务器:验证输入数据,防止注入。
- 超时设置:
XMLHttpRequest
:javascript xhr.timeout = 5000; xhr.ontimeout = () => alert('请求超时');
fetch
:javascript const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); fetch('http://localhost:3000/users', { signal: controller.signal });
- 推荐 fetch:
fetch
语法简洁,适合现代开发。XMLHttpRequest
适用于进度监控(如文件上传)。
- 调试:
- 使用浏览器开发者工具(Network 面板)检查请求和响应。
- 使用
JSON.stringify(data, null, 2)
格式化输出。
11. 总结
- 实例功能:通过 AJAX(
XMLHttpRequest
和fetch
)查询和添加 MongoDB 用户,处理 JSON 响应。 - 后端:Node.js(Express)模拟 ASP/PHP,PHP 提供等效实现。
- JSON 角色:前后端交互使用 JSON,
JSON.stringify()
和JSON.parse()
关键。 - 最佳实践:处理跨域、错误、超时,优先使用
fetch
。
如果你需要 ASP 具体实现、PHP 更多功能(如分页、搜索),或想深入某部分,请告诉我,我会提供详细代码或指导!
const express = require('express');
const { MongoClient } = require('mongodb');
const app = express();
const uri = 'mongodb://localhost:27017/myDatabase';
const client = new MongoClient(uri);
app.use(express.json());
app.use(express.static('public'));
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST');
next();
});
app.get('/users', async (req, res) => {
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('users');
const users = await collection.find({}).toArray();
res.json(users);
} catch (error) {
console.error('查询失败:', error);
res.status(500).json({ error: '服务器错误' });
} finally {
await client.close();
}
});
app.post('/users', async (req, res) => {
try {
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('users');
const user = req.body;
const result = await collection.insertOne(user);
res.json({ message: '添加成功', id: result.insertedId });
} catch (error) {
console.error('添加失败:', error);
res.status(500).json({ error: '服务器错误' });
} finally {
await client.close();
}
});
app.listen(3000, () => console.log('服务器运行在 http://localhost:3000'));
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Allow-Headers: Content-Type');
require 'vendor/autoload.php';
use MongoDB\Client;
$uri = 'mongodb://localhost:27017';
$client = new Client($uri);
$collection = $client->myDatabase->users;
$method = $_SERVER['REQUEST_METHOD'];
if ($method === 'GET') {
try {
$users = $collection->find()->toArray();
$users = array_map(function($user) {
$user['_id'] = (string)$user['_id'];
return $user;
}, $users);
echo json_encode($users);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => '服务器错误']);
}
} elseif ($method === 'POST') {
try {
$data = json_decode(file_get_contents('php://input'), true);
if (!$data || !isset($data['name']) || !isset($data['age'])) {
http_response_code(400);
echo json_encode(['error' => '无效数据']);
exit;
}
$result = $collection->insertOne($data);
echo json_encode(['message' => '添加成功', 'id' => (string)$result->getInsertedId()]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => '服务器错误']);
}
} else {
http_response_code(405);
echo json_encode(['error' => '方法不支持']);
}
?>
<!DOCTYPE html>
<html>
<head>
<title>AJAX ASP/PHP 示例</title>
<style>
pre { font-size: 16px; background: #f4f4f4; padding: 10px; }
button, input { padding: 10px; margin: 5px; }
</style>
</head>
<body>
<h1>用户管理</h1>
<div>
<input id="name" placeholder="姓名">
<input id="age" type="number" placeholder="年龄">
<button onclick="addUser()">添加用户(XMLHttpRequest)</button>
<button onclick="addUserFetch()">添加用户(Fetch)</button>
</div>
<button onclick="loadUsers()">加载用户</button>
<pre id="result">点击按钮加载用户数据...</pre>
<script>
function loadUsers() {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/users', true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const users = JSON.parse(xhr.responseText);
document.getElementById('result').innerText = JSON.stringify(users, null, 2);
} catch (error) {
document.getElementById('result').innerText = '错误:JSON 解析失败';
}
} else {
document.getElementById('result').innerText = `错误:${xhr.statusText} (${xhr.status})`;
}
}
};
xhr.onerror = function () {
document.getElementById('result').innerText = '错误:网络错误';
};
xhr.send();
}
function addUser() {
const name = document.getElementById('name').value;
const age = parseInt(document.getElementById('age').value);
if (!name || !age) {
alert('请输入姓名和年龄');
return;
}
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/users', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
try {
const response = JSON.parse(xhr.responseText);
alert(response.message);
loadUsers();
} catch (error) {
alert('错误:JSON 解析失败');
}
} else {
alert(`添加失败:${xhr.statusText}`);
}
}
};
xhr.onerror = function () {
alert('网络错误');
};
xhr.send(JSON.stringify({ name, age, hobbies: ['未知'] }));
}
async function addUserFetch() {
const name = document.getElementById('name').value;
const age = parseInt(document.getElementById('age').value);
if (!name || !age) {
alert('请输入姓名和年龄');
return;
}
try {
const response = await fetch('http://localhost:3000/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name, age, hobbies: ['未知'] })
});
if (!response.ok) throw new Error(`服务器错误:${response.status}`);
const result = await response.json();
alert(result.message);
loadUsers();
} catch (error) {
alert(`添加失败:${error.message}`);
}
}
</script>
</body>
</html>