I'm using PHP to pull the events from a FullCalendar as a JSON feed but I need to support multiple domains. I need a querystring variable to specify which calendar to pull events from... is this causing a problem? Here's the FullCalendar init code:
$('#full-calendar".$id."').fullCalendar({
editable: false,
events:'http://www.mydomain.com/resources/include/calendar-events.php?cal=".$id."',
loading: function(bool) {
if (bool) $('#loading').show();
else $('#loading').hide();
}
});
The documentation says "If you need to access a feed that is in a different domain, you can use JSONP with a ? in your URL (see the JSONP discussion in $.ajax)."
But I'm not exactly sure how to do that.
Thanks for your help in advance.
Well at a high level, JSONP lets you specify the name of a callback function that you want called when the AJAX request returns with data. HTTP GET operations can happen across different domains, (when you embed an image from a different host, you are creating an HTTP GET). POST (and PUT, DELETE etc) are limited to the same domain as the document (this is called the Same Origin Policy). JSONP, adds an extra parameter (usually 'callback') with the value of a JavaScript function in your document (the callback function). The sever sending the JSON needs to know to extract the value for that parameter. Your request might look like this:
GET http://ical.example.com/cal.json?callback=_calDraw
The cal.json servlet will return this
_calDraw({event:{date:'12/25/2010',title:'Jason\'s birthday'}});
Now this bit of JavaScript references the callback function you passed into it, but without a corresponding
function _calDraw(data) {
//render stuff
}
The returned data will just fail. It's important that you have some level of trust with any server you are making a JSONP call to, because you are giving them permission to execute JavaScript in your document (they don't have to return something valid).
Hope this helps!
Related
I'm building and iOS application and
trying to get the json data from a url similar to:
example.com/ajax/u.php?callback=jQuery84054761566_1389381628746
Is anyone familiar with these types of callbacks?
Typical HTTP requests in obj-c return 200 status and a null response object with this url.
That's a JSONP callback used for...well, JSONP. JSONP is used on webpages to avoid the 'same origin' restriction. That is, a webpage loaded from a certain domain (say abc.com) cannot call/access resources on a separate domain (say xyz.com).
The way they (web front-end developers) get around this is by using the <script> tag which is exempt from this restriction. However the return of a <script> tag would just be parsed - to cause it to execute something, you tell it a function name that exists in your JavaScript code, in this case, jQuery84054761566_1389381628746.
So instead of returning a regular JavaScript object, say
{key : 'value'}
the server then returns a function invocation
jQuery84054761566_1389381628746({key : 'value'})
and you have, in your webpage JavaScript, the function definition for jQuery84054761566_1389381628746 that does something:
jQuery84054761566_1389381628746 = function(data){
alert(data.key);
};
iOS does not have this same-origin/cross-site restriction so you don't need JSONP - you can call whatever server you want.
In many example code I saw the format of .getJSON() is something like
$.getJSON("url?jsoncallback=?", function(data){
...}
And at back-end the response is written like
$response = $_GET["jsoncallback"]."(".json_encode($orders).")";
echo $reponse
I delete "?jsoncallback=?" from the url and $_GET["jsoncallback"] and square brackets at back-end and it seems that everything still works. So what is the use of that jsoncallback stuff indeed?
If you don't have the jsoncallback=? it will just do normal JSON request not JSONP*. You can do normal JSON request just fine on your own server or a server that sends CORS headers.
* forget about JSONP, this is a fancy name for inserting a script element in your document that runs code from a foreign server but with same authorization as your own scripts. The $_GET["jsoncallback"], makes it a javascript function call like this:
fn({"data": "value"});
This is the code in a script like <script src="http://foreign.org/data?jsoncallback=fn"></script>. As you can see, that's Javascript, not JSON. With this, foreign.org (or someone hacking them) can change their script to do anything with authorization on your page, so be careful when using "JSONP" and prefer CORS JSON.
The callback name is used for JSONP, which is a way to circumvent the same origin policy.
JSON callback can be used to display cross domain data with jQuery. JSONP is used to make cross domain calls since it's not allowed by the same origin policy. Check out the example below.
http://www.9lessons.info/2009/12/display-cross-domain-data-json-callback.html
i am trying from my main web page to check and in some cases send a variable via URL like this (http://192.168.0.110/CVAL.CGI?A0=1) this is to modify the status of something in my web page depending on the value seen in the url.
Sounds like you need Ajax.
There are many javascript libraries that can help you with this functionality such as jQuery, Prototype, or one of the many found on this page.
Hope that is what you are looking for and is helpful. Next time post more specific details so we can answer your question correctly the first time. Specific, detailed examples of what you want to do are also helpful.
UPDATED:
Here is an example using the Prototype Javascript library given your example form:
new Ajax.Request('/CVAL.CGI?A0=1', {
method: 'get',
parameters: { anotherValue: 'something' },
onSuccess: function(transport) {
alert(transport.responseText); // this is what the server returned
}
});
This would result in a request to /CVAL.CGI?A0=1&anotherValue=something. Whatever CVAL.CGI returns in response to that request, is available from transport.responseText.
This way, the user never has to leave the page or submit a form but it is all done behind the scenes. Your parameters can be any values you want to send which you can grab from form fields or other user input. You can return responses in JSON to make accessing the return data easier as well. Change method from 'get' to 'post' to do post requests.
So far when creating AJAX requests I have been posting to a separate PHP file. Is it possible to create a jQuery AJAX request that calls a PHP function rather than posts to a separate page?
If you could send me any examples or documentation would be great.
I believe there's a fundamental misunderstanding of how the technology works here.
AJAX (Javascript), Flash, or any client-sided technology cannot directly call PHP functions (or other languages running on the server).
This is true for going the other way around as well (eg: PHP can't call JS functions).
Client and server codes reside on different machines, and they communicate through the HTTP protocol (or what have you). HTTP works roughly like this:
Client (eg: browser) sends a REQUEST -> Server processes request and sends a RESPONSE -> Client gets and displays and/or processes the response
You have to see these requests and responses as messages. Messages cannot call functions on a server-side language directly 1, but can furnish enough information for them to do so and get a meaningful message back from the server.
So you could have a handler that processes and dispatches these requests, like so:
// ajax_handler.php
switch ($_POST['action']) {
case 'post_comment':
post_comment($_POST['content']);
break;
case '....':
some_function();
break;
default:
output_error('invalid request');
break;
}
Then just have your client post requests to this centralized handler with the correct parameters. Then the handler decides what functions to call on the server side, and finally it sends a response back to the client.
1 Technically there are remote procedure calls (RPCs), but these can get messy.
AJAX requests call a URL (make a HTTP request), not a file, in most cases the URL is translated by the server to point at a file (or a php script in your case), but everything that happens from the HTTP request to the response that is received is up to you (on your server).
There are many PHP frameworks that map URL's to specific php functions, AJAX is just an asynchronous way to access a URL and receive a response.
Said URL CAN trigger the server to call a specific function and send back a response. But it is up to you to structure your URL's and server side code as such.
If you're asking whether you can call any arbitrary PHP function with AJAX the answer is no*, for obvious security reasons (in addition to the technical reasons). You could make a PHP script that does different things depending on what parameter it's given (for example, execute a single function) if you don't want to create multiple separate files.
*Although you could make a script that would execute any arbitrary PHP command coming from the client, but that would be very, very, very unwise.
Short answer is "no" but the real answer is that you can fake it. NullUserException's answer is good. You create a server that will take the function name and its parameters. Then the server executes the function, and returns the value.
This was done a while back via a protocol called XML-RPC. There was also an effort called JSON-RPC that used some JS techniques.
One things that's cool about JS is that you can do things like this:
var base64_decode = create_remote_call('base64_decode');
function create_remote_call(name) {
return function(x) {
jQuery.getJSON('url/server.php',
{func:name,arg:x},
function(d){return d;});
}
}
A call to base64_decode('sarefdsfsaes') will make a ajax request and return the value.
That code probably won't work because it hasn't been tested, but it's a function that produces a function that will call the server, and then return the value. Handling more than one argument requires more work.
All that said... in my experience, it's usually good to make all network communications explicit instead of disguising it as a regular function.
you may achieve the same result using a bridge, like my phery library http://phery-php-ajax.net you can call PHP functions directly from Javascript and deal with the value. The AJAX is bound to DOM elements, so you can manipulate the calling DOM or just use jQuery from the PHP side. An example would be:
Phery::instance()->set(array(
'phpfunction' => function(){
return PheryResponse::factory()->jquery('body')->addClass('whoops');
}
))->process();
and in the javascript side (or HTML)
phery.remote('phpfunction');
the equivalent to the https://stackoverflow.com/a/7016986/647380 from John Kawakami answer, using phery is:
function base64($data){
return !empty($data['encode']) ? base64_encode($data['content']) : base64_decode($data['content']);
}
Phery::instance()->set(array(
'base64' => 'base64'
))->process();
function base64(content, decode, output){
phery.remote('base64', {'content': content, 'encode': decode ? 1 : 0}, {'type':'text'}).done(output);
}
base64('asdf', false, function(data){
console.log(data); // or assign to some variable
});
since AJAX is asynchronous and you can't just return a value from the AJAX call, you need a callback, but this would suffice.
Help, if you can-
The situation:
http://foobar.com includes a remotely hosted javacript file (http://boobar.com/stuff.js).
The goal is to just get an alert from the remotely hosted php script on foobar.com
I have tried the following code in stuff.js:
$.ajax({
type: "GET",
url: "http://www.boobar.com/script.php?callback=?",
dataType: 'jsonp',
success: function(result) { alert(result); }
});
No luck.
$.getJSON("http://www.boobar.com/script.php?jsonp=?",
function(data) { alert(data); }
);
Also no luck.
On the php side I have tried both the following:
return json_encode(array(0 => 'test'));
echo json_encode(array(0 => 'test'));
In Firefox I get a security error. I understand that it thinks I'm violating the security model. However, according to the jquery documentation, I should be able to accomplish this.
The error seems to be a security feature of the Same Origin Policy: to simplify, you can only make AJAX requests for stuff on the originating server (http://foobar.com). One way around this is to make a simple facade on the originating server, e.g.:
<?php
// this file resides at http://foobar.com/getstuff.php
echo file_get_contents('http://www.boobar.com/script.php?callback=?'
. $possibly_some_other_GET_parameters );
?>
Then, from foobar.com, you can make an AJAX request for http://foobar.com/getstuff.php (which in turn makes a HTTP GET request from your web server to boobar.com and sends it back to the browser).
To the browser, the request goes to the origin server, and is allowed (the browser has no way of knowing that the response comes from somewhere else behind the scene).
Caveats:
the PHP config at foobar.com must have allow_url_fopen set to "1". Although this is the default setting, some servers have it disabled.
the request to www.boobar.com is made from foobar.com server, not from the browser. That means no cookies or user authentication data are sent to www.boobar.com, just whatever you put into the request URL ("$possibly_some_other_GET_parameters").
You can get data from another server asynchronously using script tags and json:
<script type="text/javascript" src="http://somesite.com/path/to/page/"></script>
You can use this to dynamically load a remote javascript (by created a new script element and setting the src attribute, then loading into the DOM), which could set a variable. However, you need to really trust the remote site, because the JS will be evaluated without any precondition.
There is a method called window.name transport or window.name method which uses a general browser bug(not sure if this is a bug actually). You make the request through an iFrame and the loaded page puts the information you need to the "name" property of the JavaScript window object of itself.
This method uses a "blank.htm" since it first navigates to the target page and then goes back to the blank.htm page to overcome the "same origin policy" restriction.
Dojo have implemented this and you can find a more detailed explanation here.
Also I have implemented a cross-domain XMLHttpRequest object based on this method in the library I have written which can be found here.
You may not be able to use the library since it will need 1 or 2 additional libraries which can be found here.
If you need further help in implementing it in your style, I'll try to do my best.
So what I ended up doing, since it was just a GET - no data need to be retrieved - I used JQuery to create a hidden iframe with the URL including the variables I wanted to pass set as the source. Worked like a charm. To all who provded feedback - Thanks!
How about this !! Using a php proxy.
Cross-Domain AJAX calls using PHP
http://www.phpfour.com/blog/2008/03/cross-domain-ajax-using-php/
jQuery .ajax also has a setting 'crossDomain'.
http://api.jquery.com/jQuery.ajax/
crossDomain (default: false for same-domain requests, true for cross-domain requests)
Type: Boolean
If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)