Send JSON data from Javascript to PHP?
Simple example on JavaScript for HTML input-fields (sending to server JSON, parsing JSON in PHP and sending back to client) using AJAX:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
</head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<body>
<div align="center">
<label for="LName">Last Name</label>
<input type="text" class="form-control" name="LName" id="LName" maxlength="15"
placeholder="Last name"/>
</div>
<br/>
<div align="center">
<label for="Age">Age</label>
<input type="text" class="form-control" name="Age" id="Age" maxlength="3"
placeholder="Age"/>
</div>
<br/>
<div align="center">
<button type="submit" name="submit_show" id="submit_show" value="show" onclick="actionSend()">Show
</button>
</div>
<div id="result">
</div>
<script>
var xmlhttp;
function actionSend() {
if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else {// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
var values = $("input").map(function () {
return $(this).val();
}).get();
var myJsonString = JSON.stringify(values);
xmlhttp.onreadystatechange = respond;
xmlhttp.open("POST", "ajax-test.php", true);
xmlhttp.send(myJsonString);
}
function respond() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById('result').innerHTML = xmlhttp.responseText;
}
}
</script>
</body>
</html>
PHP file ajax-test.php :
<?php
$str_json = file_get_contents('php://input'); //($_POST doesn't work here)
$response = json_decode($str_json, true); // decoding received JSON to array
$lName = $response[0];
$age = $response[1];
echo '
<div align="center">
<h5> Received data: </h5>
<table border="1" style="border-collapse: collapse;">
<tr> <th> First Name</th> <th> Age</th> </tr>
<tr>
<td> <center> '.$lName.'<center></td>
<td> <center> '.$age.'</center></td>
</tr>
</table></div>
';
?>
I've gotten lots of information here so I wanted to post a solution I discovered.
The problem: Getting JSON data from Javascript on the browser, to the server, and having PHP successfully parse it.
Environment: Javascript in a browser (Firefox) on Windows. LAMP server as remote server: PHP 5.3.2 on Ubuntu.
What works (version 1):
1) JSON is just text. Text in a certain format, but just a text string.
2) In Javascript, var str_json = JSON.stringify(myObject)
gives me the JSON string.
3) I use the AJAX XMLHttpRequest object in Javascript to send data to the server:
request= new XMLHttpRequest()
request.open("POST", "JSON_Handler.php", true)
request.setRequestHeader("Content-type", "application/json")
request.send(str_json)
[... code to display response ...]
4) On the server, PHP code to read the JSON string:
$str_json = file_get_contents('php://input');
This reads the raw POST data. $str_json
now contains the exact JSON string from the browser.
What works (version 2):
1) If I want to use the "application/x-www-form-urlencoded"
request header, I need to create a standard POST string of "x=y&a=b[etc]"
so that when PHP gets it, it can put it in the $_POST
associative array. So, in Javascript in the browser:
var str_json = "json_string=" + (JSON.stringify(myObject))
PHP will now be able to populate the $_POST array when I send str_json via AJAX/XMLHttpRequest as in version 1 above.
Displaying the contents of $_POST['json_string']
will display the JSON string. Using json_decode() on the $_POST array element with the json string will correctly decode that data and put it in an array/object.
The pitfall I ran into:
Initially, I tried to send the JSON string with the header of application/x-www-form-urlencoded and then tried to immediately read it out of the $_POST array in PHP. The $_POST array was always empty. That's because it is expecting data of the form yval=xval&[rinse_and_repeat]. It found no such data, only the JSON string, and it simply threw it away. I examined the request headers, and the POST data was being sent correctly.
Similarly, if I use the application/json header, I again cannot access the sent data via the $_POST array. If you want to use the application/json content-type header, then you must access the raw POST data in PHP, via php://input, not with $_POST.
References:
1) How to access POST data in PHP: How to access POST data in PHP?
2) Details on the application/json type, with some sample objects which can be converted to JSON strings and sent to the server: http://www.ietf.org/rfc/rfc4627.txt
Javascript file using jQuery (cleaner but library overhead):
$.ajax({
type: 'POST',
url: 'process.php',
data: {json: JSON.stringify(json_data)},
dataType: 'json'
});
PHP file (process.php):
directions = json_decode($_POST['json']);
var_dump(directions);
Note that if you use callback functions in your javascript:
$.ajax({
type: 'POST',
url: 'process.php',
data: {json: JSON.stringify(json_data)},
dataType: 'json'
})
.done( function( data ) {
console.log('done');
console.log(data);
})
.fail( function( data ) {
console.log('fail');
console.log(data);
});
You must, in your PHP file, return a JSON object (in javascript formatting), in order to get a 'done/success' outcome in your Javascript code. At a minimum return/print:
print('{}');
See Ajax request return 200 OK but error event is fired instead of success
Although for anything a bit more serious you should be sending back a proper header explicitly with the appropriate response code.