Im not quite sure how to explain this but im experimenting with creating my own API. At the moment things are working quite well by doing cURL requests or jQuery AJAX requests.
My problem is I see using other APIs that you specify you want a JSON response in the arguments root of the jQuery object. With my API I have to specify I want a JSON response in the data argument. How exactly are APIs picking up this JSON argument? Example:
$.ajax({
url: 'url',
type: 'POST',
data: {dataType : 'json'}, //I need this for PHP to know I want a JSON response
dataType: 'json' //how do other APIs grab this on the API side?
}).
done(function(response){
console.log(response);
});
In PHP I can only pickup the data object VIA $_POST. If I remove the data object from the AJAX request I dont get data back. So what should I do in PHP to pickup the "root" dataType argument to know to return JSON?
<?php echo serialize($_POST) ?>
When you set dataType, jQuery sends that info as part of the Accept header, it probably looks something like this: Accept: application/json, text/javascript, */*; q=0.01.
On the PHP side of things, you can access it with the $_SERVER superglobal:
$accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null;
if ($accept && false !== stripos($accept, 'application/json')) {
// send back JSON
}
If you happen to be using Symfony's HttpFoundation component, it has some nice facilities to deal with Accept headers:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\AcceptHeader;
$r = Request::createFromGlobals();
$accept = AcceptHeader::fromString($r->headers->get('Accept') ?: '*/*');
if ($accept->has('application/json')) {
// send json
} elseif ($accept->has('application/xml')) {
// send xml
} else {
// send whatever
}
Related
I have setup a page that takes the data from a form, serializes into JSON and then uses AJAX to call a PHP file to process the form data and send it to an API via cURL.
How can I get the response from the API to come back as part of the AJAX's success function?
At the start of my project, I was able to accomplish this because I was using the php as an include. But cannot use that method because the file is being executed from the AJAX call not from an include.
I tried to follow this tutorial, but just kept catching errors.
I've also scoured, reviewed and attempted more suggestions from various posts on this site than I can even count. Now, I'm asking for some help.
Here is the pertinent ajax on my index.php file.
$.ajax
({
type: "POST",
dataType : 'json',
async: false,
url: 'save_application.php',
data: { filename: fileName, applicationData: jsonFormString, job: adid },
success: function () { console.log("done");},
failure: function() {console.log('error');}
});
And here is the relevant part of the save_application.php file.
$curl = curl_init();
curl_setopt_array($curl, array(
//stuff here
));
$applicantresponse = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
And lastly, the $applicantresponse that comes back is formatted like this:
{
"applicationId": 123456789,
"links": {
"link1": "https://thisisalinkforLINK1.html", //THIS IS THE VALUE I WANT
"link2": "https://thisisalink.html",
"link3": "https://thisisalink.html"
}
}
Ultimately, I want to set a variable to the value for links->resume (ex: var resumeLink = (something goes here); \\returns https://thisisalinkforLINK1.html) back on my index.php within the success function so I can use that response for some other to-dos.
You need to output $applicantresponse from your save_application.php file so that it's returned to your calling code, and you need to change the success function in your ajax code to then use that data. It'll look something like this:
$applicantresponse = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
echo json_encode($applicantresponse);
and then...
$.ajax
({
...
success: function (data) {
console.log(data.links.link1);
// do something with the data that was returned
},
...
});
One thing that is important is that your php code not output any other text to the client. All other echo, print, debugging calls, all of that stuff, has to be removed, because otherwise you're not sending back valid json encoded data that jQuery knows how to interpret.
It looks like save_application.php uses the data submitted by $.ajax for the curl request, and you need to send part of the curl response back to the client to be used in the success function.
The curl response is already JSON, so the simplest thing to do is just
echo $applicantresponse;
which will send the entire curl response back to the client.
If you only want to send one of the links of it, you'll need to decode it and extract the specific piece you want, then re-encode that piece.
$applicantresponse = json_decode($applicantresponse);
$link = $applicantresponse->links->link1;
echo json_encode($link);
I'm trying to make an AJAX call in Vue to a PHP script, but it doesn't seem to be working.
Vue:
methods: {
onSubmit () {
if (this.valid) {
this.$http.post('http://remindwordserver.loc/register.php', {test: 'test'}).then(response => {
console.log(response.body)
}, response => {})
}
}
},
PHP:
`<?php
print_r($_POST);`
$_POST is empty
What am I doing wrong?
I'm not too familiar with PHP, but I'll give it a go.
The $_POST variable only contains data from the request when the HTML Content-Type of the request is application/x-www-form-urlencoded or multipart/form-data. vue-resource by default sets the Content-Type of the request to application/json.
If you want to access JSON data in your PHP script, you'll have to decode the request data from JSON. See Receive JSON POST with PHP.
I have an function with angular doing this:
$http({
method:"post",
url:"savedata.php",
data:$.param($scope.cat),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function(data){
and in savedata.php I do this:
$name=$_POST['name'];
that's fine and I can work with it. But if you do this in the browser: savedata.php?name=dog it will process the data.
How can I avoid this? How can I only allow php to process data sent from the angular function, and not from the browser with the url.
Or are there better ways of working like this?
I'm trying to let savedata.php function as an restfull API, and I don't want it to be meddled with except from my own functions.
$_POST is not populated from the URL query string. If this is happening, you have an error in your code.
Do it with default Content-Type which is application/json.
You will get application/json data on PHP side in php input.
$post = json_decode(file_get_contents("php://input"), true);
print_r($post);
I've been debugging this for hours. Tried to set the header etc but no luck!
My controller
$http({
url: 'http://myphp.php/api.php',
method: "POST",
data: {'wtf':'test'}
})
.then(function(response) {
console.log(response);
},
function(response) { // optional
// failed
}
);
and my php
<?php
echo "test";
echo $_POST["wtf"];
?>
In my network tab this is how it look like
Not sure what's wrong man, really exhausted, I'm stuck for hours! Why my $_POST['wtf] didn't echo?
$http is serializing the data to JSON in the request body but PHP's $_POST is looking for key/values parsed from posted form data. These are two different mechanisms for posting data so you need to choose one and use that mechanism on both sides.
You have two options to solve this:
In your PHP code, parse the request body as JSON data and then use that object to retrieve your data. See this StackOverflow question for more information.
Modify your $http request to post the data as form data. See this StackOverflow question for more information.
$http.post (by default) does not send the data as key/value pairs. It sends it as post request.
Therefore, in your php script you should consume it like this:
$input = file_get_contents('php://input');
And then parse it like this:
$data = json_decode($input, true);
I have an ajax call, that sends form data to a php function. Since I read a lot that using contentType: 'application/json' is best practice I wanted to give it a try as well. But unfortunately my script doesn't return anything when I use it. If I remove it, the script does what it is supposed to do.
Do you have any idea what the reason might be and why? Thank you!
$('#Form').submit(function(e) {
e.preventDefault();
var content = $(this).serialize() + "&ajax=1";
$.ajax('app/class/controller/contactForm.php', {
type: "POST",
//contentType: 'application/json',
dataType: 'json',
data: content,
success: function(result) {
console.log(result);
}
});
})
and my PHP:
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
echo json_encode(validateForm($_POST));
}
When using contentType: 'application/json' you will not be able to rely on $_POST being populated. $_POST is only populated for form-encoded content types.
As such, you need to read your data from PHP raw input like this:
$input = file_get_contents('php://input');
$object = json_decode($input);
Of course if you want to send application/json you should actually send JSON, which you are not doing. You either need to build the object serialization to JSON directly, or you need to do something like this - Convert form data to JavaScript object with jQuery - to serialize the object from the form.
Honestly in your case, since you are dealing with form data, I don't quite think the use case for using application/json is there.
The best practice you refer to is about the server script setting the Content-Type for JSON to "application/json":
Header('Content-Type: application/json; charset=UTF8');
This is because otherwise a default Content-Type will be sent, often a catch-all text/html, and this could lead to an incomprehension with the client.
If you do not specify yourself a Content-Type in the jQuery request, jQuery will determine the most appropriate one. The problem here is that you were sending a POST form, for which the default Content-Type set by jQuery is application/x-www-form-urlencoded, which tells PHP to decode the data as POST fields and populate $_POST. Your script would have then recovered its parameters from $_POST (or maybe $_REQUEST).
By changing it to application/json, $_POST will no longer be populated, the receiving script operation won't receive the parameters where it was expecting to, and the operation breaks.
So you either need to:
not specify the Content-Type yourself (better, IMHO)
set a Content-Type of application/x-www-form-urlencoded; charset=UTF-8
set a Content-Type of application/json; charset=UTF-8 and modify the script to parse the POST stream and decode the JSON data; see this answer.
The third option requires proper handling of php://input.
The PHP script should be setting the Content-Type header.
if(isset($_POST['ajax']) && $_POST['ajax'] === '1') {
header('Content-Type: application/json');
echo json_encode(validateForm($_POST));
}