Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Substitute for Cross-domain request with JavaScript

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.

like image 394
Heinrich Apfelmus Avatar asked Jun 27 '26 07:06

Heinrich Apfelmus


2 Answers

Some options:

  1. If you're in control of the servers and your users will be using an up-to-date web browser, you can use CORS. Sadly, there is no CORS support in IE7 or below. In IE8, it's there, but you have to use an XDomainRequest instead of an XMLHttpRequest (other browsers, like Chrome and Firefox, handle CORS completely transparently with XMLHttpRequest).
  2. If not, you can use JSONP, which works with all browsers.
  3. You can use 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).
  4. Another alternative, for public stuff, is using YQL as a proxy.
  5. If all of those fail, your only real option is to have a proxy script on your server that you query, which then uses server-side code to query the resource from the other domain (since this restriction only applies client-side).

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).

like image 150
T.J. Crowder Avatar answered Jun 28 '26 21:06

T.J. Crowder


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).

like image 27
Alfred Avatar answered Jun 28 '26 22:06

Alfred



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!