ScriptCase空白应用中DNI字段blur事件调用PHP函数失败求助
在ScriptCase空白应用中DNI字段blur事件无法触发PHP函数的问题
我在ScriptCase中使用空白应用,尝试为HTML代码里的DNI字段添加blur事件监听器,当用户输入身份证号码并触发该事件时,调用API获取该号码持有人的全名。目前监听器已正确添加,但对应的PHP函数未被调用,请问哪里操作出错了?
以下是我设置的代码:
?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> <link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'> <style> body { font-family: 'Roboto'; } </style> <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script> <title>CLBS | Registro de Usuario</title> </head> <body style="overflow: hidden !important"> <div class="container-fluid"> <div class="row mt-5"> <div class="col-6" style="border-radius: 5px !important; border: solid 1px #F3F3F3 !important"> <div class="row" style="background-color: #485EA2 !important; height: 40px !important"> <label class="col-12 col-form-label"><b style="color: white !important; font-size: 16px !important">Registro de Usuario</b></label> </div> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> <div class="row mt-2"> <label class="col-form-label col-4"><b>DNI</b></label> <div class="col-7"> <input id="input_dni" type="text" class="form-control" style="height: 27px !important" name="input_dni"> </div> </div> </form> </div> </div> </div> <script> const inputDNI = document.querySelector('#input_dni'); inputDNI.addEventListener("blur", () => { const dni = inputDNI.value; //console.log(dni); var result="<?php buscarEnReniec(dni); ?>"; document.write(result); }); </script> </body> </html> <?php function buscarEnReniec($dni){ echo $dni; sc_select (user, "SELECT nombres FROM pru_seg_usuarios WHERE nro_documento = " . $dni); if(count({user} -> fields) === 0) { $curl = curl_init(); $token = 'token'; curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.apis.net.pe/v2/reniec/dni?numero=' . $dni, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => 0, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 2, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Referer: https://apis.net.pe/consulta-dni-api', 'Authorization: Bearer ' . $token ), )); $response = curl_exec($curl); curl_close($curl); $persona = json_decode($response, true); echo $persona; } else { $params = array( 'title' => 'Aviso', 'type' => 'warning', 'timer' => '2000', 'showConfirmButton' => false, 'position' => 'top-end', 'toast' => true ); sc_alert('Ya existe un usuario con el nro de documento ingresado.', $params); } }
错误原因分析
- 前后端执行逻辑混淆:PHP是服务器端代码,页面加载时就会执行完毕;而JavaScript是客户端代码,在页面加载后触发blur事件才运行。你在JS中直接写
<?php buscarEnReniec(dni); ?>,这里的dni是JS变量,PHP无法识别,且这段PHP代码在页面加载时就已执行,和后续的blur事件完全无关。 - ScriptCase函数使用错误:
sc_select的SQL语句未给$dni加引号,会导致语法错误;判断查询结果的count({user}->fields)不符合ScriptCase规范,应使用sc_num_rows(user)获取结果行数。 - 页面更新方式错误:
document.write()会覆盖整个页面内容,不是正确的局部更新方式。 - API返回处理错误:直接
echo $persona输出数组会导致格式混乱,应输出JSON格式数据方便JS处理。
修正方案
1. 拆分前后端逻辑,使用AJAX调用PHP接口
PHP运行在服务器端,无法被客户端JS直接触发,需通过AJAX发送请求到服务器端处理。
前端JS修改
const inputDNI = document.querySelector('#input_dni'); // 添加显示姓名的元素 const nombreDisplay = document.createElement('span'); nombreDisplay.className = 'ml-2 text-muted'; inputDNI.parentElement.appendChild(nombreDisplay); inputDNI.addEventListener("blur", () => { const dni = inputDNI.value.trim(); if (!dni) { nombreDisplay.textContent = ''; return; } fetch(window.location.href, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: `action=buscarDNI&dni=${encodeURIComponent(dni)}` }) .then(response => response.json()) .then(data => { if (data.success) { nombreDisplay.textContent = `Nombre: ${data.nombre}`; nombreDisplay.style.color = '#28a745'; } else { nombreDisplay.textContent = data.message; nombreDisplay.style.color = '#dc3545'; // 调用ScriptCase提示框 if (typeof sc_alert !== 'undefined') { sc_alert(data.message, { title: 'Aviso', type: 'warning', timer: 2000, showConfirmButton: false, position: 'top-end', toast: true }); } } }) .catch(error => { console.error('请求出错:', error); nombreDisplay.textContent = '查询失败,请稍后重试'; nombreDisplay.style.color = '#dc3545'; }); });
后端PHP修改
将PHP代码放在HTML输出之前,处理AJAX请求:
<?php // 处理AJAX请求 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'buscarDNI') { $dni = $_POST['dni'] ?? ''; buscarEnReniec($dni); exit; } function buscarEnReniec($dni){ // 过滤输入,防止SQL注入 $dni = sc_sql_injection($dni); // 修正sc_select语法,添加引号 sc_select(user, "SELECT nombres FROM pru_seg_usuarios WHERE nro_documento = '" . $dni . "'"); if(sc_num_rows(user) === 0) { $curl = curl_init(); $token = 'token'; // 替换为你的真实API Token curl_setopt_array($curl, array( CURLOPT_URL => 'https://api.apis.net.pe/v2/reniec/dni?numero=' . $dni, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => 1, // 建议开启SSL验证,提升安全性 CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 2, CURLOPT_TIMEOUT => 10, CURLOPT_FOLLOWLOCATION => true, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_HTTPHEADER => array( 'Referer: https://apis.net.pe/consulta-dni-api', 'Authorization: Bearer ' . $token ), )); $response = curl_exec($curl); $curlError = curl_error($curl); curl_close($curl); if ($curlError) { echo json_encode([ 'success' => false, 'message' => 'API请求失败: ' . $curlError ]); return; } $persona = json_decode($response, true); if (isset($persona['nombres'], $persona['apellidoPaterno'], $persona['apellidoMaterno'])) { $fullName = $persona['nombres'] . ' ' . $persona['apellidoPaterno'] . ' ' . $persona['apellidoMaterno']; echo json_encode([ 'success' => true, 'nombre' => $fullName ]); } else { echo json_encode([ 'success' => false, 'message' => '未找到该DNI对应的信息' ]); } } else { // 获取已存在的用户姓名 sc_fetch(user); $existingName = {user}->fields->nombres; echo json_encode([ 'success' => false, 'message' => 'Ya existe un usuario con el nro de documento ingresado.', 'nombre' => $existingName ]); } } ?> <!-- 这里放原来的HTML代码 -->
2. 额外注意事项
- SQL注入防护:使用
sc_sql_injection过滤用户输入,避免安全风险。 - Token保密:不要将API Token硬编码在代码中,建议使用ScriptCase全局变量或配置文件存储。
- ScriptCase函数规范:确保
sc_select、sc_num_rows等内置函数的使用符合官方文档要求。
内容的提问来源于stack exchange,提问作者Paul De la cruz
相关产品推荐
相关产品推荐

