I have this fetch api in React that is sending data to the server. The server runs PHP and I'm having trouble accessing the data with $_POST or with file_get_contents('php://input');
So I want to check every step of the process until I can see where the error is. I also want to verify how the post data is being sent. ie I want to see the actual data and the full request from the browser.
Fetch request looks like this:
export function sendEmail (data) {
return fetch('http://example.com/email.php', {
method: 'POST',
credentials: 'same-origin',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}).then(response => response.json())
}
When I go into google chrome's dev tools I see the request headers, response, etc but nowhere can I see the actual data being sent. I've looked around online and no one can seem to give a clear answer.
In your dev tools, click Network tab, then do the request and click on it. Scroll to the Request body section.
Network tab
Fiddler might be helpful in this scenario. It will show you the post body sent to your PHP endpoint.
I recommend you axios, easier to check if success or error and cleaner:
Post without any body sent;
import axios from 'axios';
axios.post('http://example.com/email.php')
.then(response=>response.data)
.then(response=>console.log('Success:', response))
.catch(err=>console.log('Error: ',err))
With some arguments:
axios.post('http://example.com/email.php',
{
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(response=>response.data)
.then(response=>console.log('Success:', response))
.catch(err=>console.log('Error: ',err)
I just created an JQuery ajax function to retrieve some json-encoded data from PHP, here's my code :
file name : bank.php
$('form').on('submit', function(){
var datatobesent = $(this).serialize();
$.ajax({
data: datatobesent,
url:'data.php',
type:'GET'
})
.done(function(data){
console.log(typeof(data));
});
return false;
})
and in data.php I wrote
if(isset($_GET)){
$data = $_GET;
echo json_encode($data);
header("Content-type:application/json");
}
the question is, when I delete the line of header("Content-type:application/json"); in data.php the console.log tell that the type of data returned by ajax is string.
And when I added dataType :json`` inside the ajax function in bank.php the type changes into object
so what is the function of header("Content-type:application/json"); actually?
The function header("Content-type:application/json") sends the http json header to the browser to inform it what kind of data it expects. You can see all the http headers for each request in your browser (If you are using chrome open developer tools, go to network, adjust the view and reload the page, you will see all requests made by your browser, if you click on any on any of these requests then click on headers you will see the headers of each request).
When you use this function you will notice the http header Content-Type:application/json in the response sent from the server. If you don't use it the server will send the default which most likely is Content-type:text/html; charset=UTF-8
As #Monty stated you don't need this function if you added dataType: 'json' to your AJAX as Jquery will handle the data even it is sent with text/html header.
See Also: jQuery AJAX Call to PHP Script with JSON Return
To read more about headers : http-headers-for-dummies
My jquery code:
var jsonData;
$.ajax({
url: 'http://mysite.lv/projects/addform',
dataType: 'json',
success: function(response) {
jsonData = response;
console.log('Works');
}
});
My Controller function at http://mysite.lv/projects/addform:
$jsonData = array('x' => 'send x', 'y' => 'send y');
echo json_encode($jsonData);
In console:
GET http://mysite.lv/projects/addform 500 (Internal Server Error)
XHR finished loading: GET "http://mysite.lv/projects/addform".
A 500 error means that your PHP script is failing.
The snippet you added is valid PHP, but the problem is likely elsewhere in the PHP code (or server configuration)
Try debugging by manually loading (that is, open it in your browser) your http://mysite.lv/projects/addform page and making sure it displays the data you expect.
Also enable PHP error reporting — see How to get useful error messages in PHP? here for details.
Update IV / Current status: I've now confirmed trough another question that the character encoding of the file is fine and not the cause of the problem. I've also tested against another server and the error still persists. It does however work towards localhost.
So to summarize: JSONP call works towards localhost, but when running against external domains the response from the server is empty (no header / no http response code). When copying the requested URL and inserting it directly in a browser, the output is correct with correct formating (utf-8 / json).
Fiddle: http://jsfiddle.net/5SJvp/1/
Update III: I'm now able to get it working succesfully on localhost. However, using the exact same code (both client and server) towards my production domain it still fails. The response from the server is "empty" meaning to say it returns no http status code.
Update II: After some more debugging I noticed that the response does not include an http status code. This probably is the cause of my problem? I assume this means there is something wrong server side, but I cannot for the life of me see where.
Update I: Snip from jQuery where to request seems to halt.
// Do send the request
// This may raise an exception which is actually
// handled in jQuery.ajax (so no try/catch here)
xhr.send( ( s.hasContent && s.data ) || null );
Params (from Firebug)
_ 1356655864905
callback jQuery18308375673194150332_1356655863817
p 0522
pl 12
s false
secret ##############################
u request12341299
Request (from Firebug)
Accept text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language nb-no,nb;q=0.9,no-no;q=0.8,no;q=0.6,nn-no;q=0.5,nn;q=0.4,en-us;q=0.3,en;q=0.1
Connection keep-alive
Host localhost:8888
Referer http://localhost:8888/popup.html
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:17.0) Gecko/20100101 Firefox/17.0
X-Requested-With XMLHttpRequest
Original question:
I'm struggling with what seems to be a common problem, but I've yet to find a solution. I'm trying to execute a very simple jsonp call using jQuery. The problem is that either a) nothing is happening or b), the response from the server is empty.
I've tried several different approaches, using both the $.ajax method and the $.getJSON method. Both produce the same faulty result. Using the code below nothing happens: Using the Chrome debugger I can see that it simply stops its execution halffway trough the method. However using Wireshark I can see that the client performs the three way handshake and thusly prepars to send data, it just fails to do that.
If I remove the callback=? it does execute, however the response is malformed (or at least, I think so since I can only see a response marked with a red line in Firebug).
$.ajax({
url: "http://mydomain.com/asd.php", //"http://localhost:8888/index.php",
dataType: 'jsonp',
type: 'GET',
data: {p:p, u:u, s:symbols, pl:pl, secret:secret},
contentType: "application/json; charset=utf-8",
async: false,
success: function(data){
console.log("What " + data.test);
},
error: function(data){
console.log("failed for some reason");
}
});
Server code ($callback = $_GET["callback"]
<?php header('content-type: application/json; charset=utf-8');
.
.
.
$data = array
(
"message" => $message,
"status" => $statuscode,
"length" => strlen($message)
);
echo $callback . '('.json_encode($data) .')';
exit;
?>
Here is the server response with manually typed input.
funcName({"message":"!0b7(cb6Gv40","status":"OK","length":12})
It is hard to debug this without a jsfiddle/jsbin, so my best suggestion would be to try getting the request to work with fake, static data (just an empty JSON struct, {}, will do).
It seems that the problem might lie in how you are using json_encode, since you write that when you add the callback=? param the response looks mangled. The suggested test will let you diagnose better where the issue lies.
This will obviously NOT work if you did not set up your SSL certificates properly.
This works properly when I transform the https to http: http://jsfiddle.net/eysEe/
var u = "test";
var p = 1234;
var symbols = false;
var pl = 16;
var secret = "c68f39913f901f3ddf44c707357a7d70";
$.ajax({
url: "http://serve.pin2pass.com?index.php",
dataType: 'jsonp',
type: 'GET',
data: {
p: p,
u: u,
s: symbols,
pl: pl,
secret: secret
},
contentType: "application/json; charset=utf-8",
async: false,
success: function(data) {
$('#test').text(data.message);
},
error: function(data) {
$('#test').text("SDf");
}
});
You can tell if you have bad SSL installation when "https://serve.pin2pass.com?index.php" leads to a risky page. Maybe you never intended to put it in https mode ?
callback is the universal GET param for wrapper function name for the jsonp. When you use callback=? in jQuery request, jQuery will parse the ? into something else with a time stamp so it will be always be a unique value. The API server will wrap the json in this unique function name, and jQuery stores the name so it can use it to unwrap the response.
Some API's are not flexible and require their own specific name in which case you can use the jsonpCallback option in either $.ajax or set it globally in $.ajaxSetup
See $.ajax API docs: http://api.jquery.com/jQuery.ajax/
Starting from your code I've set it up locally and everything works as expected:
test.php :
<?php
$callback = $_GET["callback"];
$data = array
(
"message" => 'test',
"status" => 200,
"length" => strlen('test')
);
echo $callback . '('.json_encode($data) .')';
exit;
test.html :
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$(document).ready(function(){
$.getJSON("http://localhost/test.php?callback=?",
{
whatever: 1,},
function(data) {
alert("hmm");
});
});
</script>
</head>
<body>
</body>
</html>
Two things that could help you :
Not putting the callback=? in your call fails because the JSON returned from your server is not valid JSON (due to the parenthesis around your json data). $.getJSON will silently fail in this case. If you want to see the error, use $.ajax instead.
Your problem might come from the fact that you're apparently trying to use https here. In Chrome at least, making an AJAX request to an https URL with an invalid certificate (I assume your localhost or test domain doesn't have a valid certificate) just puts an error in the console. The browser never prompts with the "are you sure?" about the certificate.
Hope it helps
Hm, can you try using 'Fiddler' to debug the call? Perhaps that empty server response isn't that empty after all.
Or maybe your server has some strange security settings, and checks the REFERRER header to block out external calls?
If you can give a full url to your app I could test it for you =)
So, with the new fiddle it was much easier to work. This is a working sample of your call-
var u = "test";
var p = 1234;
var symbols = false;
var pl = 16;
var secret = "c68f39913f901f3ddf44c707357a7d70";
$.ajax({
url: "https://serve.pin2pass.com/index.php",
dataType: 'jsonp',
type: 'GET',
data: {
p: p,
u: u,
s: symbols,
pl: pl,
secret: secret
},
contentType: "application/json; charset=utf-8",
aync:true,
success: function(data) {
$('#test').text(data.message);
},
error: function(data) {
console.log("failed for some reason");
}
});
jsfiddle
I hope I am not missing something here. The only change I had to do is in the request url, from
https://serve.pin2pass.com?index.php
to
https://serve.pin2pass.com/index.php
Hope this solves it.
I tried to send the request from jquery ajax with contentType as 'text/plain'. I am unable to access the values on the server side. I am accessing the values using $_POST array in php file. Why is this happening.
jQuery AJAX code:
$.ajax({
type: "POST",
data: {o_pass:o_pass,n_pass:n_pass},
url: "changepass",
success: function(response) { alert(response); }
});
Server side:
$old_pass = $_POST['o_pass'];
$new_pass = $_POST['n_pass'];
Because POST requests should have a content type of application/x-www-form-urlencoded or multipart/form-data so that the server knows what it is dealing with.
What is the reason for sending the request as plain text?
You shouldn't have to worry about the content type, when doing a standard post request.
Try changing your url: changepass to changepass.php. You probably have an html or htm file named changepass that your server is processing your post request.