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).
Related
I'm looking for a way to interact with a form before submitting a POST like the CURLOPT_POSTFIELDS option for PHP curl provides, but with node.js.
I'm rewriting some PHP code to javascript, and it's the following line I can't find a javascript alternative for
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"rememberMe": true}');
I'm currently using the node-fetch NPM library
My javascript code so far
fetch(requestUrl,
{
method: 'POST',
headers: headers,
}
)
with the headers including content-type and authorization
Thanks to #tadman the answer was found at https://www.npmjs.com/package/node-fetch#post-with-json
By providing a body you can achieve the desired result
Final code would look like the following if JSON is the desired way to go
fetch(requestUrl,
{
method: 'POST',
body: JSON.stringify({'rememberMe': 'true'}),
headers: headers
}
)
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've been working on building an API as a learning purpose. It is essentially a twitter-like micro post API. Alongside the API I've been building a client web application powered off of the API. I am able to successfully post statuses without any problems. But now I am trying to allow users to upload an image along with the post. The client application is built using the mvc pattern. I post the submitted post to my post controller via jQuery ajax like so:
$.ajax({
url: '../../posts/newPost',
type: 'POST',
data: formData,
async: true,
success: function (data) {
console.log(data);
$('#post-form-area').removeClass('loading');
$('#post-body').val('');
$('#files').val('');
$('#attached').find('img').remove();
$('#attached').hide();
},
cache: false,
contentType: false,
processData: false
});
I am able to successfully get the file data using the $_FILES array within my controller. However, I am having a lot of difficulty figuring out how to send this to my RESTful API. I created a class to handle my API calls and here is the code for my POST method:
$ds = json_encode($params);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $ds);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request
$result = curl_exec($ch);
Here is the data that I pass to post a text only status:
$data = array('user_id' => $_SESSION['user_id'], 'body' => $body, 'time' => $timestamp);
I have tried passing $_FILES['file']['tmp_name'] as part of the array, but on API side the $_FILES array is null. I tried following this example, but I ran in to the same problem.
The way my API is set up, if the $_SERVER['request_method'] is POST I get the contents from cURL from php://input and then pass these parameters to the necessary controller. Do I need to add anything here that will give me access to the $_FILES array? I've been digging for about 3 hours now and haven't been able to find anything that has helped me, so I appreciate any help.
Thanks!
Edit:
I don't see how this is a duplicate as the link you posted that it is a duplicate of has nothing to do with uploading an image through a RESTful service...
Edit 2:
I've narrowed it down to how I am sending the data from my client application because I am successfully able to use the following command line code to upload a file:
curl -X POST -F "image=#test.JPG" http://rest.mattaltepeter.com/posts/upload
And then the code to receive it:
public function uploadAction() {
$result['success'] = move_uploaded_file($_FILES['image']['tmp_name'], SITE_ROOT . '/uploads/' . $_FILES['image']['name']);
$result['data'] = UPLOAD_DIR . $_FILES['image']['name'];
return $result;
}
I came across this tutorial and have been able to implement it fine with a static URL to an image, but that isn't very helpful as I want a user to be able to select their own image to upload with their post. So it looks like my issue is revolved around getting the full path as that tutorial mentions on line 4 of the first code block and sending it to the api. So how do I get that same information from the $_FILES array instead of a static file URL?
Finally figured it out. It had to do with using json_encode() to send my POST data. As soon as I tried it with out json_encode(), I had access to the $_FILES array. I think I'll have to add a parameter to my ApiCall->post() method to tell it if I want to json_encode() the data I wish to pass.
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 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/ .