PHP 入门教程
37.3 前端:使用
37.5 原生
PHP 与 AJAX
本教程共 65 篇 · 第 37 篇 · 更新于 2026-07-24 · 约 5 分钟阅读
PHPPHP8AJAXfetch异步请求CORS前后端交互
37. PHP 与 AJAX
本节目标:理解 AJAX 的工作原理,学会用原生
fetch和XMLHttpRequest调用 PHP 接口,实现无刷新数据交互。
AJAX(Asynchronous JavaScript and XML)让网页在不刷新的情况下与服务器交换数据。虽然名字里有 XML,但现代应用几乎都使用 JSON。
37.1 AJAX 工作原理
- 用户在页面上触发某个操作(如点击按钮、输入文字)
- JavaScript 创建请求对象,向 PHP 后端发送请求
- PHP 处理请求,返回数据(通常是 JSON)
- JavaScript 接收响应,更新页面部分内容
37.2 PHP 端:准备接口
PHP 返回 JSON 是最常见的配合方式:
<?php
// api/search.php
header("Content-Type: application/json; charset=utf-8");
$keyword = $_GET["q"] ?? "";
$keyword = htmlspecialchars(trim($keyword));
// 模拟数据库查询
$allUsers = ["张三", "张三丰", "李四", "王五", "赵六"];
$results = array_filter($allUsers, fn($name) => str_contains($name, $keyword));
echo json_encode([
"success" => true,
"data" => array_values($results),
"count" => count($results),
]);
TipPHP 8.0 起
str_contains()让字符串包含判断更直观,过去要用strpos() !== false。
37.3 前端:使用 fetch API(推荐)
fetch 是现代浏览器内置的异步请求 API,比 XMLHttpRequest 更简洁:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>AJAX 示例</title>
</head>
<body>
<input type="text" id="keyword" placeholder="输入姓名搜索">
<button onclick="search()">搜索</button>
<ul id="result"></ul>
<script>
async function search() {
const q = document.getElementById("keyword").value;
const response = await fetch(`api/search.php?q=${encodeURIComponent(q)}`);
const json = await response.json();
const list = document.getElementById("result");
list.innerHTML = "";
if (json.count === 0) {
list.innerHTML = "<li>无结果</li>";
return;
}
json.data.forEach(name => {
const li = document.createElement("li");
li.textContent = name;
list.appendChild(li);
});
}
</script>
</body>
</html>
Note
encodeURIComponent()对中文和特殊字符进行 URL 编码,避免请求参数解析错误。
37.4 前端:POST JSON 数据
<script>
async function login() {
const response = await fetch("api/login.php", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: "admin",
password: "123456",
}),
});
const result = await response.json();
if (result.success) {
alert("登录成功!");
} else {
alert("登录失败:" + result.message);
}
}
</script>
对应的 PHP:
<?php
header("Content-Type: application/json; charset=utf-8");
// 读取 POST 的 JSON 数据
$input = file_get_contents("php://input");
$data = json_decode($input, true);
$username = $data["username"] ?? "";
$password = $data["password"] ?? "";
// 验证逻辑...
if ($username === "admin" && $password === "123456") {
echo json_encode(["success" => true, "token" => "abc123"]);
} else {
echo json_encode(["success" => false, "message" => "账号或密码错误"]);
}
Tip
php://input读取原始请求体,适合接收 JSON、XML 等非表单格式的 POST 数据。
37.5 原生 XMLHttpRequest(兼容旧浏览器)
<script>
function searchClassic() {
const q = document.getElementById("keyword").value;
const xhr = new XMLHttpRequest();
xhr.open("GET", "api/search.php?q=" + encodeURIComponent(q), true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
const json = JSON.parse(xhr.responseText);
console.log(json);
}
};
xhr.send();
}
</script>
37.6 用 jQuery AJAX(传统项目常见)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(function() {
$("#keyword").on("input", function() {
const q = $(this).val();
$.get("api/search.php", { q: q }, function(data) {
const list = $("#result").empty();
if (data.count === 0) {
list.append("<li>无结果</li>");
return;
}
data.data.forEach(name => {
list.append($("<li>").text(name));
});
}, "json");
});
});
</script>
37.7 跨域问题(CORS)
如果前端和后端在不同域名,PHP 需要设置 CORS 头:
<?php
header("Access-Control-Allow-Origin: *"); // 允许所有域名
header("Access-Control-Allow-Methods: GET, POST"); // 允许的请求方法
header("Access-Control-Allow-Headers: Content-Type"); // 允许的请求头
// 处理预检请求
if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") {
http_response_code(204);
exit;
}
// 正常业务逻辑...
Note生产环境不要把
Access-Control-Allow-Origin设为*,应指定具体的可信域名,防止安全风险。
来源:参考了 runoob「AJAX 简介」「AJAX PHP」、w3cschool「PHP AJAX」等,改写后所得。