Ajax Content From Other Domains
Ajax has a built-in restriction allowing it to retrieve content only from its own domain. In other words, the domain where the web page is loaded into the browser is the only domain Ajax can retrieve content from.
This article shows you how to get around that restriction.
Ajax asks PHP or CGI or other software on the server to go get the content on another domain. That software gets the content and hands it to Ajax. Both a PHP version and a CGI version of the server software are provided below.
Getting Started Instructions
First, install one software file on your server. Then, use the Ajax engine.
These instructions assume you already have a web page with the Ajax engine from the Copy and Paste Ajax Engine article. If you don't have it already, go get it. The Ajax engine is really and truly copy 'n paste.
Determine which type of software you're more comfortable with, PHP or Perl CGI. Copy the preferred software and use a plain text processor to save it on your computer. The example further below assumes the PHP file will be named getpage.php. File names can be whatever is appropriate. If you decide on the Perl CGI one, perhaps it can be named getpage.cgi
Here is the PHP version of the software to get content from another domain.
<?php # PHP Grab 'n Relay for Ajax, version 1.0 # July 5, 2008 # Copyright 2008 Bontrager Connection, LLC /* Put allowed domain names and IP addresses between quote characters. List them below separated with a comma and optional white space and/or line breaks. Pages can only be retrieved from domains and IP addresses listed here. To retrieve pages from both example.com and www.example.com, both domains must be listed. */ $AllowedDomains = Array( "example.com", "www.example.com", "127.0.0.1" ); /* No other edits necessary. */ if( isset($_GET['url']) and preg_match('/^http:\/\//i',$_GET['url']) ) { $url = $_GET['url']; } elseif( isset($_SERVER['QUERY_STRING']) and preg_match('/^http:\/\//i',$_SERVER['QUERY_STRING']) ) { $url = $_SERVER['QUERY_STRING']; } else { exit; } $url = preg_replace('/^.+?:\/\//','',$url); $pos = strpos($url,'/'); $host = substr($url,0,$pos); $uri = substr($url,$pos); $checkdomain = $host = strtolower($host); if( empty($checkdomain) ) { exit; } if( preg_match('/:/',$checkdomain) ) { $checkdomain = preg_replace('/:.*$/','',$checkdomain); } $domainokay = false; foreach( $AllowedDomains as $domain ) { if( $checkdomain == strtolower($domain) ) { $domainokay = true; break; } } if(! $domainokay) { exit; } $content = ''; $fp = @fsockopen("$host",80,$errno,$errstr,30); if($fp) { fwrite($fp,"GET $uri HTTP/1.0\r\nHost: $host\r\n"); if( isset($_SERVER['HTTP_USER_AGENT']) ) { fwrite($fp,'User-Agent: '.$_SERVER['HTTP_USER_AGENT']."\r\n"); } fwrite($fp,"Connection: Close\r\n\r\n"); while (! feof($fp) ) { $content .= fgets($fp,1024); } fclose($fp); } if( strpos($content,"\r") > 0 ) { echo( preg_replace('/^.+?[\r\n]{4,}/s','',$content) ); } else { echo( preg_replace('/^.+?\n{2,}/s','',$content) ); } exit; ?>
Here is the CGI version of the software to get content from
another domain.
#!/usr/bin/perl # CGI Grab 'n Relay for Ajax, version 1.0 # July 5, 2008 # Copyright 2008 Bontrager Connection, LLC # List allowed domain names and IP addresses, separated # with white space and/or line breaks, between the # line like this (see below) # my $AllowedDomains = <<LIST; # and the line like this, # LIST # # Pages can only be retrieved from domains and # IP addresses listed here. To retrieve pages from # both example.com and www.example.com, both domains # must be listed. my $AllowedDomains = <<LIST; example.com www.example.com 127.0.0.1 LIST # No other edits necessary. use strict; use LWP::UserAgent; use HTTP::Request::Common; my $url = ''; if($ENV{QUERY_STRING}) { if($ENV{QUERY_STRING} =~ /^url=(.+)$/) { $url = $1; } elsif($ENV{QUERY_STRING} =~ m!^http://!i) { $url = $ENV{QUERY_STRING}; } } goto BOTTOM unless $url; my $checkdomain = lc $url; $checkdomain = $1 if $checkdomain =~ m!^http://([^/]+)!; goto BOTTOM unless $checkdomain =~ /\w/; my $domainokay = 0; $AllowedDomains =~ s/^\s*(.*)\s*$/$1/s; for my $domain (split /\s+/,lc $AllowedDomains) { if($checkdomain eq $domain) { $domainokay = 1; last; } } goto BOTTOM unless $domainokay; my ($content,$success) = (); my $ua = LWP::UserAgent->new; $ua->agent($ENV{HTTP_USER_AGENT}) if $ENV{HTTP_USER_AGENT}; my $r = $ua->request(GET $url); $success = $r->is_success if $r->is_success; if($success) { $content = $r->content; } else { $content = 'Something is awry. Status code: '.$r->code; } print "Content-type: text/html\n\n$content"; BOTTOM: # end of script
Whichever script you decided to use, one place needs to be
customized. The script will need to be told which domain or
domains it is allowed to retrieve content from. Website IP
addresses may also be listed.
Both the PHP and the CGI scripts have the place marked where you specify the domain names.
The reason specifying allowed domains is required is to prevent cross-site scripting from getting content from just any domain and sending it to your site visitor's browser.
Whichever domains you allow the script to retrieve content from can, at any time, send content you might not expect and it could even be dangerous. It is suggested you either control the domains you list or trust them without reservations.
After the script has been updated with the allowed domains, it is ready to install.
To install the PHP version, upload the script to your server where your browser can access it. In the same directory where you have your domain's main or index page should work fine.
To install the CGI version, Perl modules LWP::UserAgent and HTTP::Request::Common need to be available on your server. Most hosting companies provide those modules. If in doubt, ask your hosting company or use Master Pre-Installation Tester to find out.
To install, upload the CGI script to your server in a directory allowed to run Perl CGI software. Upload with an FTP program as a plain text file (not as binary), then give the uploaded file 755 permissions.
To test, first determine the URL of a web page to retrieve the content of. The web page must be on a domain that the script is allowed to retrieve content from.
Now, into your browser's address bar, type the URL of the script, followed by a question mark ("?"), followed by the URL of the web page.
The script should retrieve the web page at the URL and display it in the browser.
Instructions for Using Ajax to Retrieve Content From Other Domains
You'll need three things:
- The web page with the Ajax engine.
- The URL of the script you just installed.
- The URL of a web page on one of the allowed domains.
On the web page with the Ajax engine, you should already have a div ready to contain the content that will be retrieved. If unsure, see the Copy and Paste Ajax Engine article for instructions.
We'll assume the div's id value is "MyUniqueID" like the example in the above-mentioned article.
Let's further assume the script you just uploaded is at http://(YourDomain)/getpage.php and that the web page you will be retrieving is at http://example.com/apage.html
Here is a way to retrieve content from that other domain with Ajax and insert it into the web page currently in the browser.
<a href="javascript:GetContent('/getpage.php?url=http://example.com/apage.html','MyUniqueID')"> Click to get the page at the other domain. </a>
That's all there's to it. Simply click the link and the
content at http://example.com/apage.html will be inserted
into your web page.
Uses for Ajax with Content from Other Domains
The example of retrieving a web page from another domain and inserting it into the current web page was just an example. In a real implementation, Ajax is likely to retrieve content generated by other scripts.
And that is where the power of Ajax and it's elegant ease of use can be appreciated.
As a possibly obvious example, a feedback form on one domain can be used on all of your domains. The form can be loaded immediately after the web page, completely bypassing any delay the form load might otherwise have required. If the form needs to be changed, one change changes it everywhere. (If you've had to fight form spam, you will appreciate that.)
The latest bid, the current weather, the time, the most recent forum or blog post, specials from other domains, widgets, all are examples of content that can be inserted into web pages after the pages have been loaded into the site visitor's browser.
Consider that the output of software on any of your domains can be inserted into web pages on your other domains. That's the elegance and sheer pleasure of using Ajax this way.
Will Bontrager