jQuery JSONP Call towards PHP backend: No HTTP response - php

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.

Related

Request to api using jquery ajax with php

hi guys i'm getting stuck in my code i'm requesting to a php api to get data with using jquery ajax. please help me with a solution
Ajax code
$.ajax({
url: request_url+"courses.php",
type: 'POST',
dataType: 'jsonp',
cors: true ,
contentType:'application/json',
data: { request_courses: courses },
secure: true,
headers: {
'Access-Control-Allow-Origin': '*',
},
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa(""));
},
success: function (data){
console.log("helo "+data);
}
});
Php Api code
if(isset($_POST['request_courses'])){
$courses = mysqli_query($conn, "SELECT * FROM `courses`");
while ($rows = mysqli_fetch_assoc($courses)) {
$data[] = $rows;
}
echo json_encode(array('status' => 1,'message'=>'responce_courses','data'=>$data));
}
Error While runing this code
courses.html:1 A cookie associated with a cross-site resource at http://localhost/ was set
without the `SameSite` attribute. A future release of Chrome will only deliver cookies with
cross-site requests if they are set with `SameSite=None` and `Secure`. You can review
cookies in developer tools under Application>Storage>Cookies and see more details at
https://www.chromestatus.com/feature/5088147346030592 and
https://www.chromestatus.com/feature/5633521622188032.
Access to XMLHttpRequest at 'file:///home/punkaj/Music/Cordova/ithub/www/index.html' from
origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for
protocol schemes: http, data, chrome, chrome-extension, https.
jquery.js:2 GET file:///home/punkaj/Music/Cordova/ithub/www/index.html net::ERR_FAILED
send # jquery.js:2
ajax # jquery.js:2
h # plugins.js:45
i # plugins.js:45
dispatch # jquery.js:2
y.handle # jquery.js:2
First off, are you sure of the file URLs? 'file:///home/punkaj/Music/Cordova/ithub/www/index.html' seems a bit sketchy IMO. Make sure that it's correct.
And secondly, looks like the AJAX referenced file (courses.php) is trying to set a new cookie on the browser, which is a bad practice in REST APIs. It's better to just return/output whatever value you want, and when you have that value in your 'success' AJAX function, you can save it there as a cookie back in the original script.
Lastly, it looks like you're getting the file directly by using an FTP protocol (file:///) rather than an HTTP protocol (http://) to get the content of the HTML file. Can't provide any further assistance on that without seeing the source code

Json request to another domain

Im trying to make a request from one server to another with json and php.
my html page:
$.ajax({
type: "POST",
url: "https://api.domain.com/gateway/partners/create_account.ajax.php",
dataType: 'jsonp',
crossDomain: true,
data: { "name" : "Test name"},
success: function(data)
{
console.log(data.responseText);
}
});
My php looks like this:
$name = $_GET['name'];
$data = array("Hello", $name);
echo json_encode($data);
I want to receive on my console: Hello Test name
What did I do wrong?
You are:
Telling jQuery to process the response as JSONP
Writing PHP that will output JSON (not JSONP) … presumably with a text/html content-type.
Trying to make a POST request instead of a GET request. JSONP only supports GET.
Trying to treat the data returned by the request as if it were an XHR object.
The minimal example of a JSONP response would be:
<?php
header("Content-Type: application/javascript");
$name = $_GET['name'];
$data = array("Hello", $name);
echo $_GET['callback'];
echo "(";
echo json_encode($data);
echo ");";
Then you need to alter the JS so that type: "POST" becomes type: "GET" and console.log(data.responseText); becomes console.log(data);
Alternatively, you could use another technique to bypass the same origin policy and still use POST.
The jsonp is a old practice and a insecure one because any one can call to your script. To is very default tor retrieving errors when a jsonp call fails.
You can implement CORS headers in your request, and then you can use just a simple XHR call.
Addeding the header:
Access-Control-Allow-Origin: *
Will fix your issue, but is better use the exact domain instead of the wildcard.

Need assistance with cURL. Need to replace ajax call

My client wants me to implement a page. On this page I made an API call using AJAX (as shown in code).
jQuery.ajax({
url: endpoint,
type: "POST",
cache:false,
data: {
url:"link-rest/sweepstakes/claim",
userId:193298,
prizeRank:2,
sweepStakeId:186
},
dataType: "json",
headers: {
Authorization:token
},
success: function(json){
callback(json);
},
error: function(xhr, status, error){
callback(errorHandle(2));
}
});
But now he wants to use this page for SEO aswell. For that I have to make an API call in php. I have never worked with cURL before. And the examples on stackoverflow does not seem to work for me. I have Wamp Server installed and the php_curl extension has been activated. All services for wamp have also been restarted. This is what I tried to implement.
$json_url = 'link-rest/sweepstakes/claim&userId=193298&prizeRank=2&sweepStakeId=186&Authorization=ams0TGpFek5EazBNekExTmprd01EYz1NVGt6TQ';
$ch = curl_init($json_url);
$options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
);
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
var_dump(json_decode($result));
But all that is printed on my screen is "null". Can anyone please tell me what I am doing wrong here?
The basic problem with the code is that you are using a relative URI and not an absolute one.
You also seem to be trying to provide a request encoded in JSON, but the Ajax appears to use standard form encoding and only expects JSON in the response
A more fundamental problem is that you are using cURL in the first place. link-rest/sweepstakes/claim is presumably handled via PHP, so you should refactor out the bits you want to call into a library and then call that library from the function you are writing. (While turning the page that handles the Ajax request into a simple View around it).

Creating a restful API using PHP as server and jQuery as client

I'm trying to create a Javascript client API service which calls the API of my site. This will be cross domain and i'm aware of the problems this causes. However, I need the user to send through some user credentials (whether that be their username and password encoded obviously or an API key + secret) so that I can return user specific details.
I initially looked at using the jsonp datatype however this doesnt allow you to set any custom headers so ruled this out.
I've been searching the web for a while and been unable to find a secure way of doing this cross domain, has anyone had any success with this and can give me some advice?
UPDATE:
I've tried this following code as suggested by lu1s, however I get an alert of 'boo' as stated n the error function..
$.ajax({
url: 'http://www.dotsandboxes.co.cc/__tests/cors.php',
type: 'GET',
dataType: 'json',
success: function() { alert('hello!'); },
error: function() { alert('boo!'); },
beforeSend: function (xhr) {
xhr.setRequestHeader('securityCode', 'Foo');
xhr.setRequestHeader('passkey', 'Bar');
}
});
Thanks
You can. Try adding the Allow-Access-Control-Origin: * to your HTTP response headers, as well as the correct content-type.
Try with a simple PHP script like this:
<?php
header('Access-Control-Allow-Origin: *');
header('Content-type: text/json');
echo json_encode(array('success'=>true,'data'=>'foobar'));
?>
Check this site to read more info about cross-origin: http://enable-cors.org/
About the authentication, it's NOT recommended to send usernames or passwords, even if they're encrypted. As you stated, it's better to pass a token in the URL. Best if following standards like http://oauth.net/2/ .

How can I use JSONP to download client-side javascript objects?

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.

Categories