Accessing and decoding JSON sent from JavaScript to PHP - javascript

So I have a form, I took the contents of its inputs, threw them into an array, had it made into a JSON and then sent it to PHP so it can in turn decode and enter it into a database. I know it'd be easier to just use a <form method="POST" action="phpfile.php"> but I can't have this redirecting to another page, especially since my PHP is not embedded into HTML, instead it handles things offsite. Otherwise it'd be simpler to just use $_POST["name"] to get what I need. Nonetheless, this page in particular is supposed to create the user, receive a server response, that the user has been entered into the database and then is given an alert with a button to be redirected to the main page.
So anyway here are the relevant sections of this whole process.
JavaScript:
window.onload = function findSubmitButton() {
var button = document.querySelector(".send_info").addEventListener("click", serverInteraction);
}
function serverInteraction() {
var xmlhttp;
var inputArray;
var finalArray = [];
var JSONArray;
if (window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
throw new Error("Your browser is not compatible with XMLHTTP");
return false;
}
inputArray = document.querySelectorAll("input[type=text]");
for(var i = 0; i < inputArray.length; i++){
finalArray[i] = inputArray[i].value;
}
console.log(finalArray);
JSONArray = JSON.stringify({finalArray: finalArray});
console.log(JSONArray);
xmlhttp.open("POST","phpFiles/sendUserInfo.php", true);
xmlhttp.setRequestHeader("Content-type","application/json");
xmlhttp.send(JSONArray);
}
PHP:
<?php
$finalArray = json_decode($_POST['finalArray']);
var_dump($finalArray);
?>
That var_dump simply returns a null and using echo gives me nothing, except a warning that my array variable isn't initialized through XDebug. I'm not quite sure what I'm doing wrong here, I've been following this just like the tutorials tell you to do it, and isn't generating the array. I've also tried $_POST['JSONArray']without any luck in case that was how it was supposed to go. Also tried file_get_contents('php://input') which sends an empty string as well.

You can't get your data from $_POST if you put JSON in your post body.
see this question Receive JSON POST with PHP. php can't handle application/json properly.
For your var_dump is empty, try this
var_dump(file_get_contents('php://input'));
var_dump(json_decode(file_get_contents('php://input'), true));
you will see your data.
And if you send your data without change it to JSON, you will get wrong data.
eg: your finalArray is ['a','b','c'] and you send it directly.
var_dump(file_get_contents('php://input'));
you will see php got string a,b,c instead of ['a','b','c']
So if you want to use $_POST to receive data, you need to use application/x-www-form-urlencoded. you can use jquery to do it. see http://api.jquery.com/jquery.ajax/
$.ajax({
method: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
})
.done(function( msg ) {
alert( "Data Saved: " + msg );
});
it will serialize your js object into x-www-form-urlencoded and php will handle it properly.
use chrome's dev tools, switch to network and see the request payload and response would be helpful for you.

You are bypassing $_POST by sending the the data as "Content-type","application/json" .
The data will instead be set in the body of request and can be retrieved using file_get_contents("php://input")
For further discussion see file_get_contents("php://input") or $HTTP_RAW_POST_DATA, which one is better to get the body of JSON request?
Generally there is no need to send your data as json to php

Related

How to receive HTTP POST parameters on vue.js? [duplicate]

I am trying to read the post request parameters from my HTML. I can read the get request parameters using the following code in JavaScript.
$wnd.location.search
But it does not work for post request. Can anyone tell me how to read the post request parameter values in my HTML using JavaScript?
POST data is data that is handled server side. And Javascript is on client side. So there is no way you can read a post data using JavaScript.
A little piece of PHP to get the server to populate a JavaScript variable is quick and easy:
var my_javascript_variable = <?php echo json_encode($_POST['my_post'] ?? null) ?>;
Then just access the JavaScript variable in the normal way.
Note there is no guarantee any given data or kind of data will be posted unless you check - all input fields are suggestions, not guarantees.
JavaScript is a client-side scripting language, which means all of the code is executed on the web user's machine. The POST variables, on the other hand, go to the server and reside there. Browsers do not provide those variables to the JavaScript environment, nor should any developer expect them to magically be there.
Since the browser disallows JavaScript from accessing POST data, it's pretty much impossible to read the POST variables without an outside actor like PHP echoing the POST values into a script variable or an extension/addon that captures the POST values in transit. The GET variables are available via a workaround because they're in the URL which can be parsed by the client machine.
Use sessionStorage!
$(function(){
$('form').submit{
document.sessionStorage["form-data"] = $('this').serialize();
document.location.href = 'another-page.html';
}
});
At another-page.html:
var formData = document.sessionStorage["form-data"];
Reference link - https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage
Why not use localStorage or any other way to set the value that you
would like to pass?
That way you have access to it from anywhere!
By anywhere I mean within the given domain/context
If you're working with a Java / REST API, a workaround is easy. In the JSP page you can do the following:
<%
String action = request.getParameter("action");
String postData = request.getParameter("dataInput");
%>
<script>
var doAction = "<% out.print(action); %>";
var postData = "<% out.print(postData); %>";
window.alert(doAction + " " + postData);
</script>
You can read the post request parameter with jQuery-PostCapture(#ssut/jQuery-PostCapture).
PostCapture plugin is consisted of some tricks.
When you are click the submit button, the onsubmit event will be dispatched.
At the time, PostCapture will be serialize form data and save to html5 localStorage(if available) or cookie storage.
I have a simple code to make it:
In your index.php :
<input id="first_post_data" type="hidden" value="<?= $_POST['first_param']; ?>"/>
In your main.js :
let my_first_post_param = $("#first_post_data").val();
So when you will include main.js in index.php (<script type="text/javascript" src="./main.js"></script>) you could get the value of your hidden input which contains your post data.
POST is what browser sends from client(your broswer) to the web server. Post data is send to server via http headers, and it is available only at the server end or in between the path (example: a proxy server) from client (your browser) to web-server. So it cannot be handled from client side scripts like JavaScript. You need to handle it via server side scripts like CGI, PHP, Java etc. If you still need to write in JavaScript you need to have a web-server which understands and executes JavaScript in your server like Node.js
<script>
<?php
if($_POST) { // Check to make sure params have been sent via POST
foreach($_POST as $field => $value) { // Go through each POST param and output as JavaScript variable
$val = json_encode($value); // Escape value
$vars .= "var $field = $val;\n";
}
echo "<script>\n$vars</script>\n";
}
?>
</script>
Or use it to put them in an dictionary that a function could retrieve:
<script>
<?php
if($_POST) {
$vars = array();
foreach($_POST as $field => $value) {
array_push($vars,"$field:".json_encode($value)); // Push to $vars array so we can just implode() it, escape value
}
echo "<script>var post = {".implode(", ",$vars)."}</script>\n"; // Implode array, javascript will interpret as dictionary
}
?>
</script>
Then in JavaScript:
var myText = post['text'];
// Or use a function instead if you want to do stuff to it first
function Post(variable) {
// do stuff to variable before returning...
var thisVar = post[variable];
return thisVar;
}
This is just an example and shouldn't be used for any sensitive data like a password, etc. The POST method exists for a reason; to send data securely to the backend, so that would defeat the purpose.
But if you just need a bunch of non-sensitive form data to go to your next page without /page?blah=value&bleh=value&blahbleh=value in your url, this would make for a cleaner url and your JavaScript can immediately interact with your POST data.
You can 'json_encode' to first encode your post variables via PHP.
Then create a JS object (array) from the JSON encoded post variables.
Then use a JavaScript loop to manipulate those variables... Like - in this example below - to populate an HTML form form:
<script>
<?php $post_vars_json_encode = json_encode($this->input->post()); ?>
// SET POST VALUES OBJECT/ARRAY
var post_value_Arr = <?php echo $post_vars_json_encode; ?>;// creates a JS object with your post variables
console.log(post_value_Arr);
// POPULATE FIELDS BASED ON POST VALUES
for(var key in post_value_Arr){// Loop post variables array
if(document.getElementById(key)){// Field Exists
console.log("found post_value_Arr key form field = "+key);
document.getElementById(key).value = post_value_Arr[key];
}
}
</script>
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
var formObj = document.getElementById("pageID");
formObj.response_order_id.value = getParameterByName("name");
One option is to set a cookie in PHP.
For example: a cookie named invalid with the value of $invalid expiring in 1 day:
setcookie('invalid', $invalid, time() + 60 * 60 * 24);
Then read it back out in JS (using the JS Cookie plugin):
var invalid = Cookies.get('invalid');
if(invalid !== undefined) {
Cookies.remove('invalid');
}
You can now access the value from the invalid variable in JavaScript.
It depends of what you define as JavaScript. Nowdays we actually have JS at server side programs such as NodeJS. It is exacly the same JavaScript that you code in your browser, exept as a server language.
So you can do something like this: (Code by Casey Chu: https://stackoverflow.com/a/4310087/5698805)
var qs = require('querystring');
function (request, response) {
if (request.method == 'POST') {
var body = '';
request.on('data', function (data) {
body += data;
// Too much POST data, kill the connection!
// 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB
if (body.length > 1e6)
request.connection.destroy();
});
request.on('end', function () {
var post = qs.parse(body);
// use post['blah'], etc.
});
}
}
And therefrom use post['key'] = newVal; etc...
POST variables are only available to the browser if that same browser sent them in the first place. If another website form submits via POST to another URL, the browser will not see the POST data come in.
SITE A: has a form submit to an external URL (site B) using POST
SITE B: will receive the visitor but with only GET variables
$(function(){
$('form').sumbit{
$('this').serialize();
}
});
In jQuery, the above code would give you the URL string with POST parameters in the URL.
It's not impossible to extract the POST parameters.
To use jQuery, you need to include the jQuery library. Use the following for that:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" type="text/javascript"></script>
We can collect the form params submitted using POST with using serialize concept.
Try this:
$('form').serialize();
Just enclose it alert, it displays all the parameters including hidden.
<head><script>var xxx = ${params.xxx}</script></head>
Using EL expression ${param.xxx} in <head> to get params from a post method, and make sure the js file is included after <head> so that you can handle a param like 'xxx' directly in your js file.

Passing XMLHttpRequest to PHP results in empty $POST

So far, I have been working on some code, and have been troubleshooting for awhile and I'm pretty sure my syntax is correct. I've been having to work around a broken testing environment so I can't use normal breakpoints to test this on the backend.
I have the following function in javascript:
function ns_submit_form_inpage(path, data){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4) {
alert("Message Sent");
}
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
var temp_string = array_to_string(data);
alert("data:"+ temp_string);
request.send(data);
}
And the following code in PHP:
<?php
mail("my_email#example.com", "Array: ". print_r($_POST, true), "From:test#example.com");
?>
I call the function, pass my path in along with an array. I get an email and a proper alert, so I know my function is called and the right file is hit and fires. A also know that right before I send off the data, they data is properly in the keyed array (e.g. first_name::bob, last_name::doe). However, the email I receive reads "Array: Array()" and confirmation via my "Message Sent" alert.
I've narrowed down where I think my error could be, and I'm done to pretty much nothing left, it feels like the array is just disappearing into the ether of the internet.
I found my issue. As mentioned, I was sending the data as an array. Although PHP reads the accepted data as an array, and I'm sending an array, the method by which the array is sent (application/x-www-form-urlencoded) doesn't USE an array. It uses a string. So, I had to change the array into a string following the format of "first_name=bob&last_name=doe&foo=bar". Now it works.

json from js to php - failed to open stream: http request failed

I am trying to send some json data from js to php, and pass it to mongo by REST.
The following outputs json string (that works fine later if I just put it as string in PHP file, please see snippet below).
JS to send json:
var s = JSON.stringify(send); //s contains previous data in arrays, etc
ic(s);
function ic(s){
var ajaxUrl = './iM.php';
$.getJSON(ajaxUrl,
{da: s},
function(data) {
console.log (data);
});
}
in iM.php:
$s = $_GET["da"]; // <-- doesn't work
//$s = '{"r":"pax","c":1,"w":["kiwi","melon"],"g":["cat","dog"]}'; //<-- works fine
$opts = array(
"http" => array(
"method" => "POST",
"header" => "Content-type: application/json",
"content" => $s,
),
);
$context = stream_context_create($opts);
$result = file_get_contents("https://api.mongolab.com/api/1/databases/$db/collections/$collection?apiKey=$key", false, $context);
var_dump($result); // Dumps the response document
At the firefox debugger, I can see the file is actually being called, however No data is added.
error_log file is created:
failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request
I also tried urlencode($s) in php, still not working.
$db, $collection and $key are defiend in php, no problem there.
What am I missing?
Basically JSON.stringify(send) function is designed in such way that it will make your json into what you are getting.
JSON.stringify(value[, replacer[, space]])
You should use this function properly. read the docs to know more.
Its basically useful if you have input value as JS array or JS object
which can be converted to single string.
You are getting '{/"r/":/"pax/",/"c/":1 in only case if you are trying to stringify a json which already in string format.
these:
var s = ['1','2','3'];
and
var s = "['1','2','3']";
are totally different things.
If you are sending an array or json object you can even send it directly
using the code above.
for example :
send = {"r":"pax","c":1,"w":["kiwi","melon"],"g":["cat","dog"]};
ic(send);
function ic(s){
var ajaxUrl = 'im.php';
$.getJSON(ajaxUrl,
{da: s},
function(data) {
console.log (data);
});
}
make sure to handle array at php side properly.
Like if you want return json, do:
$s = $_GET["da"]; //this will be array.
var jsonObject = json_encode($s);
or you can stringify it there and then provide.
or else just send string and then use json_decode to make it json in php

Can't display JSON on page

I have been trying to get my JSON code from a PHP file which is connected to my database to display on my website using an XMLHttpRequest, but we cant split them and display it.
We are using an php file example.php that does the following:
function jsonFromQuery($result) {
if (mysql_num_rows($result) > 0) {
while($r = mysql_fetch_array($result, MYSQL_ASSOC)) {
$json[] = $r;
}
} else {
$json = "Table is empty";
}
return json_encode($json);
}
This will display the json code as following on the website if you open the php file:
[{"UserID":"2","Firstname":"Piet","Lastname":"Klaas","Age":"23","Specialization":"Voet","Branch":"Been","Interests":"Hoofd","Hospital":"OLVG","Email":"pietklaas#gmail.com","ProfilePicture":""}]
With this we use the following javascript file to request this php file and stringify and try and display it.
var request = new XMLHttpRequest;
request.open('GET' , 'http://myurl.nl/example.php', false);
request.send(null);
if (request.status == 0)
console.log(request.responseText);
var obj = JSON.stringify(request);
var firstname = obj.Firstname;
document.writeln(firstname);`
But I get a massive string which includes the type status etc. And don't know how to split this up to display on their own. For example only Firstname = Piet on the page.
When you get the data back from PHP it's already in the form of a string. You need to use JSON.parse() to convert it into an object you can use. Try...
var obj = JSON.parse(request.responseText);
var firstname = obj[0].Firstname;
document.writeln(firstname);`
Note as well that the Json you're getting back is a list of objects: [{...},{...},{...}], so you can't just call .Firstname as you haven't specified which object you care about. Hence the [0] in the example above to pick out the first object.
One other thought... At present if your PHP doesn't find any results it's going to send back something that isn't in the format you're expecting. Consider either wrapping the list in an object with a status...
{
"Success": true,
"Results": [{...}, {...}]
}
Or make the PHP script return a different HTTP code to indicate failure (404 seems appropriate here)
For future reference, JSON.stringify does the opposite - it takes a complex object and converts it into Json
You are parsing the whole XMLHttpRequest object
var obj = JSON.parse(request);
try using just the response body
var obj = JSON.parse(request.responseText);

Using AJAX to access to the Twitter API

I'm thinking about adding some twitter functions in my web-application, so I started doing some tests. I checked the way to call the search twitter URL (more info in: http://dev.twitter.com/doc/get/search) in order to get tweets that contains the searched word/sentence. I realized that you can do it in php just getting the JSON file that the search URL returns with the file_get_contents() function. Also you can do it directly in JavaScript creating a script object, appending it to the body and use the callback parameter of the search URL to process the data.
Different ways to do, but that's the way I finally did it:
MAIN HTML FILE:
<title>Twitter API JSON</title>
<script type="text/javascript">
//function that created the AJAX object
function newAjax(){
var xmlhttp=false;
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
xmlhttp = new XMLHttpRequest();
}
return xmlhttp;
}
//function that search the tweets containing an specific word/sentence
function gettweets(){
ajax = newAjax();
//ajax call to a php file that will search the tweets
ajax.open( 'GET', 'getsearch.php', true);
// Process the data when the ajax object changes its state
ajax.onreadystatechange = function() {
if( ajax.readyState == 4 ) {
if ( ajax.status ==200 ) { //no problem has been detected
res = ajax.responseText;
//use eval to format the data
searchres = eval("(" + res + ")");
resdiv = document.getElementById("result");
//insert the first 10 items(user and tweet text) in the div
for(i=0;i<10;i++){
resdiv.innerHTML += searchres.results[i].from_user+' says:<BR>'+searchres.results[i].text+'<BR><BR>';
}
}
}
}
ajax.send(null);
} //end gettweets function
</script>
#search_word Tweets
<input type="button" onclick="gettweets();"value="search" />
<div id="result">
<BR>
</div>
</html>
PHP WHERE WE GET THE JSON DATA:
$jsonurl = "http://search.twitter.com/search.json?q=%23search_word&rpp=10";
$json = file_get_contents($jsonurl,0,null,null);
echo $json;
And that's it, in this way it works fine. I call the PHP file, it returns the JSON data retrieved from the search URL, and in the main HTML JavaScript functions I insert the tweets in the div. The problem is that at the first time, I tried to do it directly in JavaScript, calling the search URL with Ajax, like this:
MAIN HTML FILE:
//same code above
//ajax call to a php file that will search the tweets
ajax.open( 'GET', 'http://search.twitter.com/search.json?q=%23search_word&rpp=10', true);
//same code above
I thought it should return the JSON data, but it doesn't. I'm wondering why not and that is what I would like to ask. Does someone have any idea of why I can't get JSON data using the Ajax object? If the search URL http://search.twitter.com/search.json?q=%23search_word&rpp=10 returns JSON data, it should be obtained in the ajax object, right?
XHR requests are generally limited to same-domain requests; e.g, if you're on bertsbees.com, you can't use an Ajax method to pull data from twitter.com.
That said, Twitter's API supports a popular data transport method known as JSON-P, which is really just a glorified injection technique. You simply pass it a callback method, and the data returned will be wrapped in your desired function, so it gets eval'd and passed in.
You cannot make a cross domain request using javascript, unless you are doing from an browser addon.

Categories

Resources