Reputation: 11064
I have a JavaScript on a server named kopernikus.science.net
that wants to access a file on a different server named galileo.science.net
. Here a toy example of what I have in mind:
code residing on http://kopernikus.science.net/makecalendar.js :
var request = new XMLHttpRequest();
request.open("GET","galileo.science.net/calendar", false);
request.send(null);
document.getElementById("calendar").innerHTML =
"<div>" + request.responseText.split('\n')[0] + "</div>";
Unfortunately, due to the "same origin policy" of modern web browsers, the script is forbidden from accessing the data on a different domain.
Of course, my question is:
How can I access the remote file anyway?
Solutions outside JavaScript are allowed, like mirroring the file in question or tweaking
.htaccess
. What are my options? Which require the least amount of permissions on the web server?
The file in question is a calendar in vcalendar format which changes regularly. I'm on a shared host and don't have sysadmin rights, but I can run PHP and CGI scripts and can change some parts of the .htaccess
file.
Upvotes: 2
Views: 1382
Reputation: 48367
Assuming you can deploy PHP on kopernikus.science.net, why not just proxy it there...
<?php
header('Content-Type: application/x-javascript');
print file_get_contents('http://galileo.science.net/calendar');
(and of course you could potentially cache it briefly on the proxy and client to cut down on network noise)
Update
If you want to cache....
<?php
header('Content-Type: application/x-javascript');
define("CACHEDIR", '/tmp/webcache/');
$cache_time=14 * 24 * 60 * 60; // cache for 2 weeks
$key=sha1('http://galileo.science.net/calendar');
if (@filemtime(CACHEDIR . $key) > time() - $cache_time) { // cache good
print file_get_contents(CACHEDIR . $key);
} else { // cache stale
$freshcopy=file_get_contents('http://galileo.science.net/calendar');
print $freshcopy;
if (!file_put_contents(CACHEDIR . $key, $freshcopy)) {
// report a problem writing files
}
}
Upvotes: 1
Reputation: 1074969
Some options:
XDomainRequest
instead of an XMLHttpRequest
(other browsers, like Chrome and Firefox, handle CORS completely transparently with XMLHttpRequest
).document.domain
to specify that both of those pages (if they're really subdomains of the same science.net
domain) are in the same origin. That works well across browsers, but it has the disadvantage that you first have to load the target document into a window (probably a hidden iframe) before you can access it, because the target document also has to set document.domain
(to show that it wants to cooperate with you).Those are listed in roughly the order in which I would use them. E.g., use CORS if you control the servers and know your clients will be using up to date browsers; if not, look at JSONP (although from your comment below, you probably can't); if not either of those, perhaps document.domain
is the answer; etc., etc., working down the list to the option of last resort (proxying).
Upvotes: 8
Reputation: 19831
This is a very known problem and JSONP is solution of the problem. You can google and fine a tons of information on that. You might consider this as example of usage JSONP with and without jQuery.
http://www.beletsky.net/2010/07/json-jsonp-and-same-origin-policy-issue.html
Upvotes: 0
Reputation: 61793
Unfortunately, due to the "same origin policy" of modern web browsers, the script is forbidden from accessing the data on a different domain.
But what you could do is use json-p.
Script and JSONP requests are not subject to the same origin policy restrictions.
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-1.4.4.js"></script>
</head>
<body>
<div id="images">
</div>
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
tags: "cat",
tagmode: "any",
format: "json"
},
function(data) {
$.each(data.items, function(i,item){
$("<img/>").attr("src", item.media.m).appendTo("#images");
if ( i == 3 ) return false;
});
});</script>
</body>
</html>
As a side note the modern browser support CORS(Internet Explorer 8+, Firefox 3.5+, Safari 4+, and Chrome).
Upvotes: 1