javascript - Ajax 请求保持在 readyState=1
问题描述
正如标题所说,我试图在这个 HTML 中使用 ajax,并在 php 文件的选择列表中接收所选车辆以将其插入数据库。在此之后,如果插入正确,则假设 php 会发回与新插入关联的 id(autoincrement) 并将其显示在 HTML 上。问题是 ajax 连接在 readyState=1 处停止(就在打开通信之后)并且控制台日志中没有显示错误。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<select name="type" id="type">
<option value="Coche">Car</option>
<option value="Motocicleta">Cicle</option>
<option value="Barco">Ship</option>
</select>
<button id="btn_search">Search</button>
<div class="List" id="List">
</div>
<script type="text/javascript">
var xhreq=new XMLHttpRequest();
var btn_search=document.getElementById("btn_search");
var type=document.getElementById("type");
btn_search.addEventListener("click",find_veh);
function find_veh(event){
console.log("Find_veh1-> onreadystate:"+xhreq.readyState);
xhreq.open("GET","Ej1.php?q="+type.value,true);
console.log("Find_veh2-> onreadystate:"+ xhreq.readyState);
xhreq.onreadystatechange= show_veh;
xhreq.send(null);
console.log("Find_veh3-> onreadystate:"+ xhreq.readyState);
}
function show_veh(){
if((xhreq.readyState==4) && (xhreq.status==200)){
console.log("Show_veh correct")
document.getElementById("show_vehi").innerText=xhreq.responseText;
}else {
console.log("Error in show_veh");
}
}
</script>
</body>
</html>
PHP
<?php
$dbConn = new mysqli("192.168.1.62", "root", "pass", "AJAX");
if ($dbConn->connect_error) {
} else {
if (isset($_GET["q"])) {
$q = $_GET["q"];
$query = 'SELECT id FROM Vehiculos WHERE tipo='.$q.";";
$result = $dbConn->query($query);
$listHTML .= "<ul>";
while($idVehi = $result->fetch_assoc()){
$listHTML .="<li>".$idVehi["id"]."</li>";
}
$listHTML .="</ul>";
echo $listHTML;
}
}
解决方案
上面的代码似乎缺少带有 ID 的 HTML 元素,show_vehi
ajax 回调使用它来显示结果。与您打开 XMLHttpRequest 对象然后执行实际请求的方式相比,这种方式似乎很奇怪——我通常希望 XMLHttpRequest 在发出请求时打开,而不是在页面加载时打开。
从本质上讲,你的 ajax 似乎没有任何本质上的错误~它可以工作,所以也许是对 XHR 请求的各个阶段的误解,导致了对readyState
保持在 1 的担忧。
以下对您的原始 javascript 进行了一些细微修改,以指示您可能没有注意到的信息(回调错误并不是真正的错误),并且因为测试页面被称为ej1.php
ajax 请求,所以这里通过发送一些在同一页面上处理随机文本作为回复而不是实际的数据库查询。
<?php
if( !empty( $_GET['q'] ) ){
exit('Some sort of response for the ajax callback to process...'.date(DATE_ATOM));
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<select name="type" id="type">
<option value="Coche">Car</option>
<option value="Motocicleta">Cicle</option>
<option value="Barco">Ship</option>
</select>
<button id="btn_search">Search</button>
<button id="btn_search_alternative">Search (Alternative)</button>
<div class="List" id="List"></div>
<div id='show_vehi'></div>
<script>
var css={
red:'color:red',
green:'color:green',
blue:'color:blue'
}
function ajax( url, type, callback ){
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if( this.status==200 && this.readyState==4 ){
console.info( '%cAfter Response: %s', css.green, xhr.readyState );
callback( this.response );
}
};
console.info( '%cBefore Open: %s', css.red, xhr.readyState );
xhr.open('GET', url+'?q='+type,true );
console.info( '%cBefore Send: %s', css.blue, xhr.readyState );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send( null );
}
document.getElementById('btn_search_alternative').addEventListener('click',function(e){
function callback(r){
document.getElementById('show_vehi').textContent=r;
}
ajax( 'ej1.php', document.getElementById('type').value, callback );
});
/* slightly modified original */
var xhreq=new XMLHttpRequest();
console.info('After Initialisation: %d',xhreq.readyState)
var btn_search=document.getElementById("btn_search");
var type=document.getElementById("type");
btn_search.addEventListener("click",find_veh);
function find_veh(event){
console.log("Before Open: Find_veh1-> onreadystate:"+xhreq.readyState);
xhreq.open("GET","Ej1.php?q="+type.value,true);
console.log("After Open, Before Change: Find_veh2-> onreadystate:"+ xhreq.readyState);
xhreq.onreadystatechange= show_veh;
xhreq.send(null);
console.log("After Send: Find_veh3-> onreadystate:"+ xhreq.readyState);
}
function show_veh(){
if((xhreq.readyState==4) && (xhreq.status==200)){
console.log("Response received: Show_veh correct")
document.getElementById("show_vehi").innerText=xhreq.responseText;
}else {
console.log("Error in show_veh: readyState=%d status=%d",xhreq.readyState,xhreq.status);
}
}
</script>
</body>
</html>
但是 - 真正的问题在于您的 PHP 代码。SQL 语句完全容易受到 SQL 注入的攻击,因此我建议学习如何实现Prepared Statements
- 我很感激由于数据库主机的 C 类 IP 地址,目前这不是实时的,但现在是进行更改的时候了。
你可以尝试这样的事情(未经测试)
<?php
if( !empty( $_GET['q'] ) ){
$html=array();
$dbConn = new mysqli("192.168.1.62", "root", "pass", "AJAX");
$sql='select `id` from `vehiculos` where tipo=?';
$stmt=$dbConn->prepare( $sql );
$q=filter_input( INPUT_GET, 'q', FILTER_SANITIZE_STRING );
if( $stmt ){
$stmt->bind_param('s', $q );
$res=$stmt->execute();
if( $res ){
$stmt->store_result();
$stmt->bind_result( $id );
$html[]='<ul>';
while( $stmt->fetch() )$html[]=sprintf( '<li>%s</li>',$id );
$html[]='</ul>';
}
}
exit( implode( PHP_EOL, $html ) );
}
?>
推荐阅读
- python-3.x - Cartopy - 手动 set_extent
- azure - Azure bot builder 虚拟助手 - 在语言生成中使用 foreach 表达式
- c++ - Directx 11 - CompileFromFile() 未编译
- regex - Zend 中的正则表达式电子邮件验证
- python - 为什么我在运行我的 python ping 脚本时收到主机未找到错误?
- ios - 如何在 iOS 中对图像实现 XMP 预设过滤器
- r - 如何编写一个函数来根据控制数据集在 R 中剪切许多列
- javascript - 检查包含文档中所有对象ID的数组字段中是否存在对象ID的最佳方法是什么?
- python - 调用 plt.subplot() 重置子图大小
- python - Pipenv 虚拟环境将我拉入不同的目录