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.
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've been trying to figure out what's really the usage of header('Content-Type: application/json') in php scripts and I've found different questions and answers on stackoverflow about this subject but I still don't completely get it...
So here's the question : I've seen in some php projects this line of code, and I'm trying to understand
if this is used when another web page is calling this actual script (with ajax for example) so that the calling page can get a json from the php page
OR
if this script means that the php page is going to deal with json sent from another web page. Or maybe something else ???
Another thing that could help me if answered, lately I've been retrieving json from a resource (external url) with cURL and I had to put this header (Content-type:application/json) in the request. Did I send this header to the exertnal resource or was this MY header so that I can deal with the returned json ?
thanks
Ok for those who are interested, I finally figured out that header('Content-Type: application/json') is used when another page is calling the php script, so that the other page can automatically parse the result as json.
For instance i have in my test.php :
header('Content-type: application/json; charset=utf-8');
$arr = array ('a'=>1,'b'=>2,'c'=>3,'d'=>4,'e'=>5);
echo json_encode($arr); // {"a":1,"b":2,"c":3,"d":4,"e":5}
and in my main.js
function test() {
$.ajax({
url: 'test.php',
type: 'GET',
//dataType: 'html',
success: function (response) {
alert(response);
}
});
};
When I dont have dataType set to "json" or when I don't have the header in my test.php, the alert gives {"a":1,"b":2,"c":3,"d":4,"e":5} which is a string (tried with typeof(response), and when I have this header, or dataType:"json", I get [object Object] from the alert. So this header function is there to indicate to the calling pages which type of data it gives back, so that you can know how to deal with it. In my script, if I didn't have header('Content-Type: application/json'), I would have to parse the response in the javascript like this : JSON.parse(response) in order to make it a json, but with that header, I already have a json object, and I can parse it to html with jSON.stringify(response).
You should always set the Content-Type for any HTTP response to describe what you're serving in that response.
Whether it's JSON or something else, and whether it's for an AJAX request or any other kind of request.
You should also set the Content-Type for any request to describe your POST payload.
In PHP, if you don't specify the Content-Type header in the script, it will default to whatever you've configured default-mimetype to be in your php.ini file which is usually text/html.
Calling header('Content-Type: application/json') will override that default setting so that the script will respond with that Content-Type when requested.
Also, when calling curl with a Content-type:application/json header, you're specifying the content type for your request body and not for the expected reponse.
W3 Description For the Content-Type
The purpose of the Content-Type field is to describe the data contained in the body fully enough that the receiving user agent can pick an appropriate agent or mechanism to present the data to the user, or otherwise deal with the data in an appropriate manner.
Shortly speaking, just to inform the receiver what kind of data he received and consume it accordingly.
I have to research and give a presentation on receiving and parsing form data from a website but I'm unsure on how to parse the data and store it on a web server. My professor described to me that I should focus more on the web server side of this. I'm a little confused on whether I am supposed how (and what) it means to parse this info.
Am I supposed to grab the $_POST['data'] in PHP and submit this to a web server? There are no specifics on how to receive that data and parse it.
If someone could help me out with explaining to me how REST Web Services parse form data, I'd appreciate it.
The only hint my professor gave me was to search, "application form encoded". I could not find an explanation on this.
You could send data to your service by (jquery) AJAX, sending a json , jsonObject in this example:
<script type="text/javascript">
function send() {
var jsonObject = {
name: 'bobby',
address: 'st. test'
}
$.ajax({
url: '/myRestService.php',
type: 'post',
dataType: 'json',
success: function (data) {
alert(data)
},
data: jsonObject
});
}
</script>
and further, in your service (myRestService.php) you receive json, and reply some response, in this example: true, and received name
<?php
//read received JSON (you can receive by $_POST if you want, just change this line)
$data = file_get_contents("php://input");
//parse JSON to PHP object
$data = json_decode($data);
//return your service response
$jsonResponse = "{ \"response\": true, \"text\": \"Hey, your name is: " .$data->name . "\"}";
echo $jsonResponse;
exit;
}
?>
this is a very basic example how serivces works, and REST services are much more complex than your question, however this simple service example fit in your question because it's how REST services works as well.
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 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