mamad mamad - 27 days ago 11
Ajax Question

javascript JSON.parse throw Unexpected end of JSON input error

i have 2 file tst.html and tst.php

tst.html body is

<form>
<input id="search" type="text" size="30" onkeyup="showresult(this.value)" >
<div id="suggest"></div>
</form>


<script>
function showresult(val){
if(val.trim() == ""){

}else{
var xttp = new XMLHttpRequest() ;
xttp.onreadystatechange = function () {

var s = xttp.responseText ;

if(s.match("zerorow")){
document.getElementById("suggest").innerHTML = "zero" ;
}else {
try {
window.alert(s) ;
var arr = JSON.parse(s) ;

}
catch(err) {
document.getElementById("suggest").innerHTML = err.message;
}



}
};
xttp.open("POST" , "tst.php" ,true) ;
xttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded") ;
xttp.send("val="+val) ;
}
}




and tst.php

<?php
$servername = "localhost";
$dbusername = "mamad";
$dbpassword = "";
$dbname = "t1" ;

// Create connection
$conn = mysqli_connect($servername, $dbusername, $dbpassword , $dbname);

if (!$conn) {
die("Connection failedddddddddd: " . mysqli_connect_error());

}else{

$val = $_POST["val"] ;
$sql = "SELECT tag FROM tags WHERE tag LIKE '$val%'";
$result = mysqli_query($conn, $sql);

if($result){
if(mysqli_num_rows($result) > 0){
$arr = mysqli_fetch_all($result , MYSQLI_NUM) ;
echo json_encode($arr) ;
}else{
echo "zerorow" ;
}
}else{
echo die("faileddd " . mysqli_connect_error());
}

}
?>


assume in my database i have two record tag1 and tag2 in tag column
and

$arr = mysqli_fetch_all($result , MYSQLI_NUM) ;
json_encode($arr) ;


if you input t alphabet in input field tst.php
pass a 2 dimensional array as string like this [["tag1"],["tag2"]]

but

var arr = JSON.parse(s) ;


throw a syntax error with JSON.parse: unexpected end of data at line 1 column 1 of the JSON data message

and one more question i just want want column of data of table in my database is there any function that do it and give one dimensional array ?

sorry if it become long question .

Answer Source

The onreadystatechange event fires on every state change, not only if the request is finished and the result is returned.

You have to add some checks to make it work:

  • The readyState must be in status DONE, and
  • the http status must be 200

In code that looks like this:

xttp.onreadystatechange = function () {
  if(xhr.readyState === XMLHttpRequest.DONE && xttp.status === 200) {
    var s = xttp.responseText ;           

    if(s.match("zerorow")){
      document.getElementById("suggest").innerHTML = "zero" ;
    } else {
      try {
        window.alert(s) ;
        var arr = JSON.parse(s) ;
      } catch(err) {
        document.getElementById("suggest").innerHTML =  err.message;
      }
    }
  }
};

Hint: Better use only one return type. In your case JSON. In your code your mixing up different content types. That's bad style

Furthermore your sql is attackable with sql injections. This is an security and safty issue