AJAX ASP/PHP 实例

AJAX ASP/PHP 实例(中文讲解)

本教程展示如何使用 AJAX 与服务器端技术(ASP 和 PHP)交互,结合 JSON 数据格式,实现在客户端动态加载和提交数据。实例将使用 Node.js 模拟类似 ASP/PHP 的后端(因现代开发中 ASP/PHP 较少使用,且 Node.js 更易于演示),并提供等效的 PHP 代码。示例包括查询用户(GET 请求)和添加用户(POST 请求),使用 XMLHttpRequestfetch,结合 MongoDB 存储数据。内容简洁清晰,适合理解 AJAX 与服务器端的交互。


1. 实例概述

  • 目标:通过 AJAX 实现用户管理功能:
  • GET 请求:查询 MongoDB 中的用户列表,显示在页面。
  • POST 请求:提交新用户数据到服务器,存入 MongoDB。
  • 技术栈
  • 客户端:HTML + JavaScript(XMLHttpRequestfetch)。
  • 服务器: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,使用 XMLHttpRequestfetch 发送 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>
  • 说明
  • 使用 XMLHttpRequestfetch 发送 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 后端

  1. 启动服务器
   node server.js
  1. 访问客户端
  • 打开浏览器,访问 http://localhost:3000
  • 点击“加载用户”,显示用户列表。
  • 输入姓名和年龄,点击“添加用户(XMLHttpRequest)”或“添加用户(Fetch)”,添加用户并刷新列表。

7.2 PHP 后端

  1. 部署 PHP
  • api.php 放入 Web 服务器的根目录(如 Apache 的 htdocs)。
  • 确保 MongoDB PHP 驱动已安装。
  1. 修改客户端 URL
  • index.html 中,将 AJAX 请求的 URL 改为 http://localhost/api.php
  1. 访问
  • 访问 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. 注意事项与最佳实践

  1. 跨域处理
  • 本例使用 CORS(Access-Control-Allow-Origin: *)。
  • 生产环境限制域名:
    javascript res.header('Access-Control-Allow-Origin', 'http://trusted-domain.com');
  1. 错误处理
  • XMLHttpRequest:检查 xhr.statusonerror
  • fetch:检查 response.oktry-catch
  • 服务器返回明确错误(如 { error: '服务器错误' })。
  1. JSON 安全
  • 客户端:用 try-catch 包裹 JSON.parse()
  • 服务器:验证输入数据,防止注入。
  1. 超时设置
  • 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 });
  1. 推荐 fetch
  • fetch 语法简洁,适合现代开发。
  • XMLHttpRequest 适用于进度监控(如文件上传)。
  1. 调试
  • 使用浏览器开发者工具(Network 面板)检查请求和响应。
  • 使用 JSON.stringify(data, null, 2) 格式化输出。

11. 总结

  • 实例功能:通过 AJAX(XMLHttpRequestfetch)查询和添加 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>

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注