AJAX Cross Domain is a free library in Perl that allows to perform AJAX requests between different domains.
This alerts the source code of www.google.com. Run it here.
Virtually all modern server-side scripting languages support remote requests in one or another form. In client-side javascript, this functionality is not present due to the Same Origin Policy. Though this policy is necessary for a robust security model, programmers are often handicapped in their wish to send and retrieve requests to remote servers. During the last years, several proposals have been made for a more flexible (re-)design of the XMLHttpRequest object, which is the core mechanism of all AJAX based technologies. AJAX Cross Domain provides in the full functionality of the XMLHttpRequest object in a similar syntax, and can by extent handle all cross-domain requests. The core engine of AJAX Cross Domain is written in Perl and outputs its content as a javascript file.
All code blocks are fully working cut-and-paste examples and can be directly used in your own test pages.
This example alerts the response body of an URL with a query-string (run it):
This example does a remote request and shows all the response headers (run it):
This example returns only a specific header of interest (run it):
This example performs a POST request to the given URI and shows the request how it was offered to the remote resource (run it):
If postdata is present, it is assumed that the request method is meant as post even when method=post is not explicitly mentioned. The following example performs a (somewhat more complex percent-encoded) POST-request and returns the response body (run it):
This example sends a request with header User-Agent set to My cool User-Agent and header Content-Language set to en, and shows the request that was offered to the remote server (run it):
This example generates an error because uri is invalid (run it):
uri
uri is the only required parameter and identifies the remote resource. The value of uri must be enclosed by brackets and needs to be a valid URI according to RFC 3986 with a percent-encoded query-string. Valid examples of uri are:
uri=(https://www.site.com/)
uri=(https://www.site.com?name=john&email=john@hotmail.com)
uri=(https://www.site.com:8080?abc%20def)
Additionally, if left bracket or right bracket are needed in the query-string, they must be percent-encoded in order to distinguish them from the leading and trailing bracket. Although this is not required by RFC 3986, AJAX Cross Domain needs those to mark the begin and end. For example:
uri=(https://www.site.com/index.php?leftbracket=%28&rightbracket=%29)
For the same reason, the equals sign ("=") should be escaped as %3D, and the ampersand ("&") as %26 when they are not used as delimiters towards the end resource. See the section Escape Sequences of this document for further details about percent-encoding.
method
The method attribute is optional and has two possible values: get and post.
method=get is used to perform a get request. This should be the most common option. If no method attribute is given, AJAX Cross Domain defaults to method=get as well.
method=post is used to perform a post request. This is typically done for larger data, though AJAX Cross Domain is limited to maximum 2083 bytes (which should suffice for most posted data though). Posted data is always offered to the remote resource in the default application/x-www-form-urlencoded encoding type.
Some resources may demand a Content-Length header before accepting post requests.
postdata
postdata holds the data to be posted to the remote resource when using method=post. A valid example of postdata is:
postdata=(name=fred&email=fred@fred.com)
If the postdata attribute is given and method is absent, AJAX Cross Domain will assume that the request should be done using post anyway. No binary data can be offered, unless you manage to encode it into an URL that stays under 2KB (typically using Base64), and decode it back at the remote resource. Data should be percent-encoded as with uri; for more details see the section Escape Sequences. postdata is not a mandatory attribute even under method=post, since it might be desirable to post empty data.
headers
Optional attribute that indicates which headers should be sent together with the remote request. This can be anything you like. Valid examples of headers are:
headers=(Accept-Language=en&Content-Type=text/xml)
headers=(from=info@ajax-cross-domain.com)
base64
Optional attribute only to be used when the response is to be Base64-encoded. Normally this is only necessary when outputting binary content. A valid example of base64 is:
base64=1
Any other value than 1 (or when base64 is kept away) will cause the response to not be Base64-encoded. You must use Base64 for all binary content. Run a demo with a JPG-file sent as binary (wrong) or encoded in Base64 (right).
The returned ACD object holds four properties and one method.
ACD.responseText
This property returns the full body of the response.
ACD.getAllResponseHeaders
This property returns the full header list of the response.
ACD.getResponseHeader
The ACD.getResponseHeader method holds the headers that were returned by the remote resource. For example, ACD.getResponseHeader['Content-Type'] and ACD.getResponseHeader['Date'] are available in most cases. In order to make sure that a property exists, you need to feature-detect it first (see section Examples).
ACD.request
This property shows the full request as it was fired to the remote resource.
ACD.error
This property shows any errors that might have occurred.
Characters with reserved and unreserved purpose
The fully formatted URI must be valid as defined by RFC 3986. The first part should just be the path to the program /cgi-bin/ACD.ACD.js? and doesn't need any escaping. The query-string (which begins just after the question mark) needs to be escaped using percent-encoding.
According to RFC 3986, the allowed characters are divided into reserved and unreserved characters.
The unreserved characters never need any percent-encoding:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789-_.~The reserved characters are listed in the table below, and need to be written as follows in AJAX Cross Domain:
Character Percent-encoding How to write in ACD query-string ! %21 Both * %2A Both ' %27 Both ( %28 ( in reserved purpose and %28 outside reserved purpose [*] ) %29 ) in reserved purpose and %29 outside reserved purpose [*] ; %3B Both : %3A : in reserved purpose and %3A outside reserved purpose @ %40 @ & %26 & in reserved purpose and %26 outside reserved purpose = %3D = in reserved purpose and %3D outside reserved purpose + %2B %2B $ %24 Both , %2C Both / %2F / in reserved purpose and %2F outside reserved purpose ? %3F ? right behind ACD.js, otherwise %3F % %25 %25 # %23 %23 [ %5B Both ] %5D Both [*] Must always be percent-encoded inside the uri, headers and postdata attributes, see section "Escape of left and right brackets" below.
AJAX Cross Domain also understands the following ASCII characters of which RFC 2396 states that it is unwise to use them (so, it would be preferred to escape those as well):
<>\^`{}|
The double quote (") must always be escaped to %22 because it is used by <script src> as enclosing character.
Non-percent-encoded characters &, < and > must always be written as respectively &, < and > when ACD.js is called from any HTML file.
No other characters may be used except those mentioned here. Characters outside of the ASCII-range are never supported in URI's.
Example escape sequences
uri=(https://www.site.com/)
Right, because / and : cannot be escaped here since they are used with a reserved purpose.uri=(https://www.site.com/search.asp?q=test)
Right, because the last = resides inside the brackets of uri.
headers=(Content-Type=text/xml&uri=(https://www.site.com)
Wrong, because the right bracket is missing after /xml. The right writing would be:
headers=(Content-Type=text/xml)&uri=(https://www.site.com)
uri=(https:/%2Fwww.site.com/app.php?q=test)
Wrong, because / has a reserved purpose here. The right writing would be:
uri=(https://www.site.com/app.php?q=test)uri=%28https://www.site.com/)
Wrong, because left-bracket has a reserved purpose here and cannot be percent-encoded. The right writing is:
uri=(https://www.site.com/)
Additional notes
Escape of left and right brackets
Inside the uri, headers and postdata attributes, left and right bracket are used to indicate the beginning and the end of the value. This means that these characters cannot be used as such inside the value of these attributes itself. Therefore, it is mandatory to escape them as follows:
https://www.site.com?(
becomes in ACD:
uri=(https://www.site.com?%28)https://www.site.com?%28
becomes in ACD:
uri=(https://www.site.com?%2528)bracket=)&encodedbracket=%29
becomes in ACD:
postdata=(bracket=%29&encodedbracket=%2529)For all other characters, the original encoding is untouched. For example:
uri=(https://www.site.com?q=%3D+*&hl=de&otherchars=%2F^%28%22'!$%23)
remains identical.
AJAX Cross Domain does not support its own port-parameter towards the remote machine. Like XMLHttpRequest, the port 80 will be used by default. In case you need to send a request to another port, it must be included at the end of the authority-part of the URI. For example, to send a request to port 8080:
<script type="text/javascript" src="/cgi-bin/ACD/ACD.js?uri=(https://www.site.com:8080)"></script>
AJAX Cross Domain cannot be used for socket communication other than over HTTPS. AJAX Cross Domain always needs a listening web server at the remote machine to return the requested data; this cannot be another process or daemon.
You can configure the maximum allowed response size in the source code.
The maximum request size must be below 2083 characters, since that is the maximum URL-size accepted by Microsoft Internet Explorer. Other modern browsers should all support URLs over 2083 characters.
ACD.responseText holds the exact value that the remote server had outputted, except for the line-ends. Would they not be \r\n, those are always presented as \r\n anyway in ACD.responseText. The apostrophe ('), forward slash (/) and backslash (\) are escaped by a backslash (\). This notation is required for technical reasons and does not affect the string value.
AJAX Cross Domain cannot directly read or write cookies. If you plan to set a cookie depending on the kind of received data, you should code it out in the caller file. Also, AJAX Cross Domain cannot read cookies; but it is possible to offer a cookie to the remote resource in the headers section (see Attributes) by adding a line Cookie: name=value . Please bear in mind that the offered cookie is not the one from the visiting browser; but from the ACD.js user agent itself - which limits the usual application fields. When the remote resource attempts to set a cookie, the Set-Cookie header will be present in ACD.getAllResponseHeaders and ACD.getResponseHeader['Set-Cookie']. This information can further be used to set cookies at wish.
The default time-out value is 30 seconds for the remote resource to respond. This value can be modified in the configuration area of the source code.
Basic Access Authentication can be added by using an Authorization header as described in RCF2616. This practice is mostly discouraged in AJAX Cross Domain because the password must then be sent unencrypted in the query-string. Every time you invoke ACD.js from the caller (main file), the whole query-string is sent unencrypted over the network. This means that it can be eavesdropped by routers in between and stored in log files of the requested resource and/or any proxies along the route. Though it's possible to obfuscate or even encrypt the <script src> call, it can always be revealed by definition; because the obfuscation or encryption algorithms must be present in the web page itself. Usernames and passwords may never be put in the query-string when ACD.js is called from a publicly accessible web page. Protected environments such as intranets or secured web site areas might be safer, but always depending on circumstances. For example, if the main caller file is using Basic Access Authentication itself, it might be reasonable to use the same for ACD.js, albeit with the same objections as stated above. Really sensible data should never be put in the ACD.js query-string.
Any & should be written as & in the .js call (see section Examples). In case you would need not-percent-encoded < or >, you would need to write them as < and > too when writing an URL in HTML.
AJAX Cross Domain is subject to the same caching mechanisms as XMLHttpRequest plus one more level (its internal request engine). In order to make sure to not buffer any responses, use method=post or alternatively method=get with a unique query-string.
Separate HEAD-requests are not supported; this information is already present in ACD.getAllResponseHeaders both for POST and GET.
The browser requirements are very low; only one object is created and that's it. Any browser after 1995 with javascript support should run AJAX Cross Domain correctly.
When the remote server is outputting binary content (e.g. like gif or pdf), you must instruct AJAX Cross Domain to output it in the Base64 encoding (see section Attributes). You should not rely on how browsers handle raw binary content in javascript.
Though a default installation of AJAX Cross Domain should be pretty safe, it is important to understand the involved security issues.
Calling ACD.js is only allowed with certain query-strings (main rule)
A web page that attempts to call ACD.js, will only succeed if the offered query-string is allowed by ACD.js itself. In the top of the source code, the array @allowed_uris is used to define which query-strings are allowed and which aren't. This is a necessary safety restriction, because otherwise any web page can use your ACD.js installation to perform any request.
More details how to set @allowed_uris can be found in the Installation procedure. The examples on this web site use the same safety mechanisms; so that not any remote resource can be called.
Authentication of ACD.js against the remote resource (optional rule)
If your remote resource needs some form of authentication, it is important to realize that this must come from information stored in the query-string or based on the origin of ACD.js. If you have control over the remote resource, it is more recommended to use the second rather than the first. The former will always remain vulnerable because any call of ACD.js can always be deducted with its full query-string by anyone who has access to the main caller file. You can filter on the domain name and/or IP-address of ACD.js by using mod_authz_host.
All common variants of UNIX are supported as long as they are set up with Perl5+ and the Apache web server (both should normally be present by default). Your FTP account or web server must be set up with a cgi-bin directory or otherwise be configured with the possibility to execute Perl scripts. The procedure below refers to the cgi-bin directory as this is the most common place where Perl files are stored and executed; but this can be any location that supports it.
Save the AJAX Cross Domain source code to your local hard disk.
Go to the CGI-enabled directory of your web site (typically named cgi-bin) and create a subdirectory named ACD there.
Upload the source code to /cgi-bin/ACD/ and rename it to ACD.js.
Give the file the necessary execution rights: open a Telnet or SSH session and type chmod 755 ACD.js when in the directory where ACD.js was stored. Alternatively, most (S)FTP programs support the chmod command too; the rights should be set at read+write+execute for owner (rwx), read+execute for group (r-x) and read+execute for nobody (r-x), in short 755.
Now we need to tell Apache that .js extensions need to be ran as CGI. While still in the same directory, create a file named .htaccess with the following content:
These directives instruct Apache to serve .js files as CGI from the ACD-directory.
Your installation of AJAX Cross Domain is now complete. Create a web page test.htm with the following content:
Upload test.htm to your web site and run it from your browser. This should give you an alert window with the source code of Google. Note that this web page only works because the query-string is already present in @allowed_uris inside your ACD.js file.
In your test.htm file, replace www.google.com by your own preferred remote resource. Then, add this resource in @allowed_uris inside the source of ACD.js.
See Attributes to start crafting your own query-string. Write your own javascript code at wish to further parse the remote response. See section Properties and methods or use any of the Examples for a quick start.
AJAX Cross Domain works under Microsoft-based servers as well when they run ActivePerl. The chmod-command or .htaccess directives are usually not present there. If you're planning to install AJAX Cross Domain on any non-UNIX system, please refer to the manual of your Operating System how to assign file permissions, how to install Perl programs, and how to make .js extensions execute as CGI. Unfortunately, we can not give any guarantees for non-UNIX systems.
Download as txt file.
To give you a few ideas what AJAX Cross Domain can do for you:
Send an e-mail to info@ajax-cross-domain.com.
Thanks to Thomas Lahn, Dr John Stockton, Anthony Di Loreto and Ben Hines for bug tracking, testing, and general feedback.
This software is provided by myKMO, Ltd., "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author and/or myKMO, Ltd., be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damages. Should the software prove defective, you assume the cost of all necessary servicing, repair or correction. All of our rights, duties, and obligations are subject to the courts of the Kingdom of Belgium only.
Written and maintained by Bart Van der Donck 2008-2024.
Commercial software services are also available.
Page counter since 10-Dec-07:
700634
(Google Analytics)
Page last updated: Saturday, 31-Aug-24 21:42:58 CEST