0

I am trying to send json data from an HTML form back to php server via a POST method. Here is my code. It goes to fail block in callback function. Firebug console(ctrl+shift+J) displays no error.

<script> 
function ADDLISITEM(form)
{ 
var options = form.txtInput.value;
options = JSON.stringify(options);
var url = "conn_mysql.php"
var request = null;
request = new XMLHttpRequest();
request.open("POST", url, true);
request.onreadystatechange = function(){
    if (request.readyState == 4) {
            if (request.status == 200) {
                alert(request.responseText);
        } else {
            alert(request.status); 
        }
    }
}
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send("options=" + encodeURIComponent(options).replace(/%20/g, '+'));
}
</script>

conn_mysql.php

<?php  
    $json = $_POST['options'];
    $options = json_decode($json);
    $username = "user";  
    $password = "********";  
    $hostname = "localhost";  
    $dbh = mysql_connect($hostname, $username, $password) or die("Unable to 
    connect to MySQL");  
    $selected = mysql_select_db("spec",$dbh) or die("Could not select first_test");
    $query1 = "INSERT INTO user_spec (options) VALUES ('$options')";
    mysql_query($query1);
    //if(!mysql_query($query1, $dbh))
    //{die('error:' .mysql_error());} echo'success';
    $query = "SELECT * FROM user_spec";  
    $result=mysql_query($query);     
    $outArray = array(); 
     if ($result)
     { 
       while ($row = mysql_fetch_assoc($result)) $outArray[] = $row; 
     } 
      echo json_encode($outArray);
?> 
Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
XCeptable
  • 1,247
  • 6
  • 25
  • 49
  • 1
    You want us to write you the code? – Rihards Oct 31 '10 at 12:42
  • +1 Richards, @Harmen Stackoverflow is an help site... – Kyle Hudson Oct 31 '10 at 13:28
  • It might help to know what the request.status you're receiving is. If it's not 200, then what? 404? 403? 500? – stevelove Nov 01 '10 at 21:30
  • thanX steve, I did that just now before reading your comment & it was a 404. There was a mistake in php file name. thanX again – XCeptable Nov 01 '10 at 21:39
  • No problem. Glad you figured it out. – stevelove Nov 01 '10 at 21:40
  • @Brainfeeder can you explain a bit. I learned that it can be done in two ways, POST & using ajax. I was advised earlier by Mic through a stack for web app to send json data back to server by post. I am trying to follow that. – XCeptable Nov 01 '10 at 21:44
  • @Brainfeeder, the stack is:1) the user load an HTML page. 2) the page make an ajax call and get the options as a JSON(either it exists already in the database, or a new option set is generated). 3) the json is rendered using a JS templating engine (PURE in our case). 4) the user change something. 5) the same JSON is modified and sent by a POST to the server. 6) the server read that JSON and store it in the database(you would write the data to your file). And then go back to the step 4, to wait for another user change. – XCeptable Nov 02 '10 at 07:47

1 Answers1

1

Your request shows "fail" because the onreadystatechange function is called multiple times with different readyStates. Here is an improved, better indented version:

request.onreadystatechange = function(){
    if (request.readyState == 4) {
        if (request.status == 200) {
            alert('http.responseText');
        } else {
            alert('fail'); // fails here
        }
    }
}

You should only check the status when readyState reached 4.

Moreover, when assigning parameters to a URL, you should use encodeURIComponent to properly encode the parameters (e.g., when sending & in a value the parser thinks it marks the beginning of a new key/value pair). And when using POST as method, you should change all instances of %20 to + per the spec and send your data as a parameter to the send function and not concatenate it to the URL:

var url = "conn_sql.php";
…
request.send("options=" + encodeURIComponent(options).replace(/%20/g, '+'));

UPDATE: To process the sent string in PHP, use json_decode, e.g.:

<?php
    $json = $_POST['options'];
    $options = json_decode($json);
    // now $options contains a PHP object
?>

(Also see How to decode a JSON String)

Community
  • 1
  • 1
Marcel Korpel
  • 21,536
  • 6
  • 60
  • 80
  • thank you very much Marcel for all these valuable advises:-) its working now. there was a php script name mistake too. Now I have to catch this in POST in php. I think I will have to start new question if I get problem. – XCeptable Nov 01 '10 at 21:52
  • Also it was not printing any response with http.responseText, I use request.responseText & it start printing output. – XCeptable Nov 01 '10 at 21:54
  • @XCeptable: Indeed, I missed that one, but then you'll have to remove the single quotes around that variable name, too. Anyway, you're welcome. I'm glad you succeeded. – Marcel Korpel Nov 01 '10 at 22:49
  • there is still one problem. the 'alert (request.responseText)' should print the text JSON.stringify(options) which we are sending to url but it is printing the data that the program receives using getJson from same php script.it was left out yesterday night as i was not expecting if its going into success block then again it will not print what it suppose to be. – XCeptable Nov 02 '10 at 09:26
  • @XCeptable: No, that's not true. The variable `request.responseText` *should* print the received data from your PHP script. – Marcel Korpel Nov 02 '10 at 09:55
  • yes, it should. I even put null in the request.send but it still print that. I also change options to option, as options is also array in data received by getJson thinking it somehow links to that bit to no avail. request.status displays 200. error console is showing no error. Some other test if you could refer, I could do. – XCeptable Nov 02 '10 at 10:09
  • @XCeptable: So, if I understand your point correctly, your PHP script always returns the same value, or the value you send to it as a parameter of `request.send`? What do you mean by “…but it still print that”? In either case, we need to investigate your PHP script further. I suggest you ask a new question showing your current PHP script and explaining what it should do and what it wrongly does at the moment. – Marcel Korpel Nov 02 '10 at 10:29
  • NO, I did no do anything still to catch POST in php script. I am talking about what output alert shows in function that we make yesterday. if (request.status == 200) { alert(request.responseText); is outputting the json that I receive from same php script in my form. I mean that in last statement i.e. request.send("options=" +encodeURIComponent(options).replace(/%20/g, '+')); even I put null like request.send(null); but it still prints json that I receive from same url where I am POSTing this json data. I print out stringify(options) & it output correct. – XCeptable Nov 02 '10 at 10:55
  • If I comment out send statement, then no output. I commented it to check what happens as changing its content is not making any affect on output. – XCeptable Nov 02 '10 at 10:56
  • @XCeptable: That sound very strange to me. So even if you don't pass your JSON string as a parameter in `send`, your PHP script returns that string? Did you remove it from the URL you use in `request.open`? – Marcel Korpel Nov 02 '10 at 11:02
  • at the moment, my php only encodes & sends json data after getting it from mySQL like " if ($result) { while ($row = mysql_fetch_assoc($result)) $outArray[] = $row; } echo json_encode($outArray); " – XCeptable Nov 02 '10 at 11:03
  • @XCeptable: Then it's *that* what you see when outputting `request.responseText`. What's the problem with that and what do you want to achieve? BTW, please don't post chunks of code in comments, but update your question (or ask a new one, when appropriate). – Marcel Korpel Nov 02 '10 at 11:08
  • is not it like that when 'status==200', 'request.responseText' should ouput here(i.e. in ADDLISITEMS where we wrote ajax) the value that 'options' have? This is what I am understanding as I have to send that value back to php, catch there & update my database with that. But so far I am doing nothing with php. Its only sending data. I edit my code & put php script there. – XCeptable Nov 02 '10 at 11:28
  • PHP script sends this json data: [{"options":"smart_exp"},{"options":"user_intf"},{"options":"blahblah"}]. request.responseText is outputting this when ADDLISTITEMS is called. – XCeptable Nov 02 '10 at 11:42
  • @XCeptable: that's completely logical: `responseText` holds the output of your PHP script (or whatever the server outputs), not what you send to the server. And your PHP script does exactly that: get the contents of table `user_spec` and output it as a JSON encoded array. – Marcel Korpel Nov 02 '10 at 11:46
  • thanks a lot Marcel:) I have no words to thank you. Its all working now.Though there is one strange thing.The value received from post & saved into database, when is fetched, there is a space of one value after it & before it in table showing result in mysql shell. & is same with list that is populated using those vlues, list contain a space of one value both before & after a value. – XCeptable Nov 02 '10 at 14:18
  • I edited php code. Is it better to put both INSERT & SELECT in same script OR they should be in separate scripts ? – XCeptable Nov 02 '10 at 14:27
  • @XCeptable: I'm sorry, I really don't know that much of MySQL databases, so please ask a new question about that particular space issue. The same with INSERT and SELECT, but I don't think it hurts. What's generally a good practice is to put the access data (username & password) in a separate file outside the web root, so if in one way or another the PHP file itself is sent to the browser, someone cannot see your credentials directly. See http://stackoverflow.com/questions/97984/how-to-secure-database-passwords-in-php – Marcel Korpel Nov 02 '10 at 14:42
  • I think the reason stays in our code. Look, this is output from php: {"options":"55555"},{"options":""},{"options":"77777"},{"options":""},{"options":"12345"},{"options":""}], ajax is sending a empty post with each post. May be I put it in a new question. – XCeptable Nov 02 '10 at 19:48
  • I have found reason. Because insert & select both mysql statement are in same script, so even when there is no value to insert, script is called to get fetched values, insert statement is also executed & an empty(i.e. "" value for new option) row is inserted. – XCeptable Nov 03 '10 at 10:02