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'm making an AJAX call to a page /person/steve:
$.ajax({
url: '/person/steve',
method: 'POST',
dataType: 'json',
success: function(response){
console.log(JSON.stringify(response));
}
});
/person/steve consists of this code:
$person = array(
'name' => 'Steve',
'twitter' => '#stevelindstrom'
);
echo json_encode(array('data' => $person));
die;
Now, in my php, when I log the result of that json_encode using the PEAR Log class, I get:
{"data":{"name":"Steve","twitter":"#stevelindstrom"}}
Which is what I would expect, but if I look at the response in the Chrome dev tools, it shows:
[{"data":{"name":"Steve","twitter":"#stevelindstrom"}}]
Any idea why my object is getting stuck into an array? I have other pages that are nearly identical (just different data), and they show up as I would expect them to...
EDIT: I tried using JSON_FORCE_OBJECT and I'm getting the same result.
Try adding to json_encode as second argument JSON_FORCE_OBJECT
And do You return JSON or a string, I mean the Content-type header, is it text/html or (which should be in this case) application/json ?
Or maybe just JSON.stringify method wraps it into an array, try using dragonfly or other tool to see source of the server's raw response.
According to your question, the response is a json string. Which would make the JSON.Stringify call redundant. Remove that and see what happens.
I have problems in receiving POST request in PHP. I'm using JavaScript to send data to a PHP page with POST request. The JavaScript is from OpenLayers.js, and the part that sends the request looks like this:
var postrequest = OpenLayers.Request.POST({
url: "http://localhost/index.php",
data: "success",
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
In PHP, I'm using this code to see, what I'm getting:
<?php
print_r($_POST);
?>
This is what happens:
index.php receives POST request.
FireBug also informs that POST Parameters contain Success, the one that was sent.
print_r($_POST); in index.php just gives this: array() and doesn't change after the POST request from JavaScript.
So the data is sent and received, but my PHP code doesn't somehow understand it, or I'm not using the right PHP function.
Any suggestions, where to look, and what to try?
I think the "data" property needs to be an object containing key/value pairs.
eg:
var postrequest = OpenLayers.Request.POST({
url: "http://localhost/index.php",
data: {
userName: "myUsername",
password: "myPassword"
},
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});
If this works when you print_r($_POST) you should see
array("userName" => "myUsername", "password" => "myPassword")
I guess you need include XMLHttpRequest.js library, you can download it from this link
https://github.com/ilinsky/xmlhttprequest
I'm using jquery with the form plugin to handle the submit, but when the client receive the server response it cant pass it to a json object:
var options = {
success: showResponse,
dataType: 'json',
error: errorhandler
};
$('#UserEditForm').ajaxForm(options);
The server response is generate with the _json_encode_ php function.
When I submit the form, always the errorhandler function is called and I check the response with firebug it comes with some kind of a space after the first "{"
" {"status":1"}"
, that with utf-8 encode and something like:
"{"status":1}"
with iso-8859-1.
Thanks!!
Do you send headers with your server reply?
Otherwise, try:
header('Content-type: application/json');
Also, I've had problems with jQuery not reading some large chunks of data in JSON correctly, and I used the parse method from json.org:
https://github.com/douglascrockford/JSON-js/blob/master/json2.js
I'm trying to get client-side javascript objects saved as a file locally. I'm not sure if this is possible.
The basic architecture is this:
Ping an external API to get back a JSON object
Work client-side with that object, and eventually have a "download me" link
This link sends the data to my server, which processes it and sends it back with a mime type application/json, which (should) prompt the user to download the file locally.
Right now here are my pieces:
Server Side Code
<?php
$data = array('zero', 'one', 'two', 'testing the encoding');
$json = json_encode($data);
//$json = json_encode($_GET['']); //eventually I'll encode their data, but I'm testing
header("Content-type: application/json");
header('Content-Disposition: attachment; filename="backup.json"');
echo $_GET['callback'] . ' (' . $json . ');';
?>
Relevant Client Side Code
$("#download").click(function(){
var json = JSON.stringify(collection); //serializes their object
$.ajax({
type: "GET",
url: "http://www.myURL.com/api.php?callback=?", //this is the above script
dataType: "jsonp",
contentType: 'jsonp',
data: json,
success: function(data){
console.log( "Data Received: " + data[3] );
}
});
return false;
});
Right now when I visit the api.php site with Firefox, it prompts a download of download.json and that results in this text file, as expected:
(["zero","one","two","testing the encoding"]);
And when I click #download to run the AJAX call, it logs in Firebug
Data Received: testing the encoding
which is almost what I'd expect. I'm receiving the JSON string and serializing it, which is great. I'm missing two things:
The Actual Questions
What do I need to do to get the same prompt-to-download behavior that I get when I visit the page in a browser
(much simpler) How do I access, server-side, the json object being sent to the server to serialize it? I don't know what index it is in the GET array (silly, I know, but I've tried almost everything)
You need to tell the browser to visit the page, usually by setting window.location.
Since it's a string, it will be sent as part of the raw query string. Try looking in $_SERVER['QUERY_STRING'] for it.