在现代Web开发中,前端通过AJAX请求不同域名的后端API获取数据库数据是常见需求,但浏览器出于安全考虑会阻止跨域请求,以下是通过PHP后端支持AJAX跨域请求数据库的完整方案,遵循安全性和最佳实践。
核心原理:为什么需要PHP中转?
- 前端限制
浏览器同源策略禁止AJAX直接请求不同域名的接口(如前端在https://site-a.com
,PHP API在https://api-site.com
)。 - 安全风险
前端直接连接数据库会暴露敏感信息(如数据库IP、用户名密码),必须通过PHP后端中转。 - 正确流程
graph LR A[前端AJAX] --> B[PHP后端API] --> C[数据库] B -->|返回JSON数据| A
PHP后端实现跨域支持(CORS)
在PHP文件顶部添加CORS(跨域资源共享)头部,允许指定域名访问:
<?php // 允许指定的前端域名跨域访问(替换为你的前端域名) header("Access-Control-Allow-Origin: https://your-frontend-domain.com"); // 允许携带Cookie等凭证 header("Access-Control-Allow-Credentials: true"); // 允许的请求方法 header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // 允许的请求头 header("Access-Control-Allow-Headers: Content-Type, Authorization"); // 如果是OPTIONS预检请求,直接返回 if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { exit(0); } // 后续连接数据库的代码... ?>
PHP连接数据库并返回JSON
以MySQL为例,使用PDO防止SQL注入:
// 数据库配置 $host = 'localhost'; $dbname = 'your_database'; $user = 'db_user'; $pass = 'secure_password'; try { // 创建PDO连接 $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $user, $pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 执行安全查询(示例:获取用户数据) $stmt = $pdo->prepare("SELECT id, name FROM users WHERE status = :status"); $stmt->bindValue(':status', 'active', PDO::PARAM_STR); $stmt->execute(); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); // 返回JSON数据 header('Content-Type: application/json'); echo json_encode(['success' => true, 'data' => $data]); } catch (PDOException $e) { // 错误处理 header('Content-Type: application/json'); http_response_code(500); echo json_encode(['error' => 'Database error: ' . $e->getMessage()]); }
前端AJAX调用示例(jQuery)
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> <script> $.ajax({ url: 'https://api-site.com/get-data.php', // PHP后端地址 type: 'GET', dataType: 'json', xhrFields: { withCredentials: true // 如需传递Cookie }, success: function(response) { console.log('获取的数据:', response.data); }, error: function(xhr) { console.error('请求失败:', xhr.responseJSON?.error); } }); </script>
关键安全措施
- 限制跨域域名
不要使用header("Access-Control-Allow-Origin: *")
,明确指定前端域名。 - 防止SQL注入
务必使用PDO预处理语句(如bindValue()
),禁止拼接SQL字符串。 - 验证请求来源
在PHP中验证$_SERVER['HTTP_ORIGIN']
是否在白名单内:$allowedOrigins = ['https://site-a.com', 'https://site-b.com']; if (in_array($_SERVER['HTTP_ORIGIN'], $allowedOrigins)) { header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); }
- 敏感操作验证
对修改数据库的操作(POST/PUT)增加身份验证(如JWT令牌)。
替代方案:JSONP(仅限GET请求)
// PHP端 $data = ['result' => 'Hello JSONP']; echo $_GET['callback'] . '(' . json_encode($data) . ')';
// 前端 function handleResponse(data) { console.log(data.result); } const script = document.createElement('script'); script.src = 'https://api-site.com/data.php?callback=handleResponse'; document.body.appendChild(script);
⚠️ 注意:JSONP不支持POST且存在XSS风险,推荐优先使用CORS。
步骤 | 关键点 |
---|---|
设置CORS | 指定前端域名、方法、头部 |
数据库操作 | 使用PDO预处理语句防注入 |
返回JSON | 统一数据格式便于前端解析 |
前端调用 | 配置withCredentials 传递凭证 |
安全加固 | 限制域名、验证权限、过滤输入 |
遵循此方案可安全实现跨域数据库请求,实际部署时,建议:
- 使用HTTPS加密传输
- 定期更新数据库凭据
- 对API请求做速率限制
引用说明:本文技术方案基于MDN Web Docs的CORS标准、PHP官方PDO文档及OWASP安全实践,具体实现需根据项目需求调整。
原创文章,发布者:酷盾叔,转转请注明出处:https://www.kd.cn/ask/30331.html