The Pear package called HTTP Request provides an easy way to perform HTTP requests indirectly without the use of a browser. The complete functionality of the package emulates many functionalities of a browser and provides very easy API to use. This article is focussed on the use of HTTP Request for cross domain AJAX purpose.
Let us start with a short tutorial (A detailed documentation can be found on the Pear website http://pear.php.net/manual/en/package.http.http-request.php)
Making a simple HTTP Request
The HTTP Request package contains a central object called HTTP_Request object which encapsulates the HTTP Request which is made to a web server.
<?php
require_once "HTTP/Request.php";
$req =& new HTTP_Request("http://www.mabaloo.com/");
if (!PEAR::isError($req->sendRequest()))
{
echo $req->getResponseBody();
}
?>
The above piece of code makes an HTTP Request to the webserver at Mabaloo. Gets the response, that is the cookies, the headers and html which is sent back and prints the body of the response(the HTML).
Sending GET and POST data with the Request
<?php require_once "HTTP/Request.php";
$req =& new HTTP_Request("http://www.php.net");
$req->setMethod(HTTP_REQUEST_METHOD_POST);
$req->addPostData("id", "1234");
if (!PEAR::isError($req->sendRequest()))
{
$response1 = $req->getResponseBody();
}
?>
The above code creates a HTTP_Request object on for http://www.php.net/ and adds POST variables to the request. For GET data we do not have to do setMethod as GET is default. However if we use the same HTTP_Request object to make another request we can add the following lines to the previous code only.
$req->setMethod(HTTP_REQUEST_METHOD_GET);
$req->setURL("http://yahoo.com");
$req->clearPostData();
if (!PEAR::isError($req->sendRequest()))
{
echo $req->getResponseBody();
}
Handling Cookies with PHP PEAR HTTP Request
We can add cookies to the Request by using
$req->addCookie("name", "value");
However we have to remember that we have to add cookies to the request before the sendRequest() function is called.
To print cookies recieved as a response
<?php
require_once "HTTP/Request.php";
$req =& new HTTP_Request("http://mabaloo.com/");
$response = $req->sendRequest();
print_r($req->getResponseCookies());
?>
This will print the cookies which were recieved as a response.
This is about enough introduction you will need to use HTTP Request package for cross domain AJAX communication. Although the package has certain more functionality, which you can study from the documentation link given above, they will probably be not required for this tutorial.
Cross Domain AJAX - It is possible. But How??
Starting with AJAX, a strange thing about AJAX (atleast I found it strange) is that due to security issues browsers do not allow a request to be made to a different domain. As if the page in a browser is open on exampleX.com and tries to make an AJAX Request to a page on examplyY.com the browser will not allow. Till now Iframes were used in such situation with another Iframe being opened on a different domain. I have explained how to use Iframes in such cases in another one of my articles on cross domain message passing with Iframes.
Now let us continue, if the browser does not allow us to directly make a request to exampleY.com, we choose a longer way around. The method is to create a proxy page on the exampleX.com itself which relays the request to exampleY.com.
Let me explain in detail. Suppose on a page 'test.html' on exampleX.com you need to make an AJAX request to a page testY.php on exampleY.com What do we do?
First of all we create a page 'proxy.php' on the server exampleX.com itself, here is where we use the PEAR HTTP Request package. The proxy.php uses HTTP_Request object to make another request to the page on exampleY.com. Since the request is being relayed from the server and not the browser, the browser will not stop it, infact it cannot even detect it, for the browser you only made a request to 'proxy.php' . The digram below makes the picture a little clearer.
Creating the proxy
The code for the proxy.php is given below
<?php
(require_once "HTTP/Request.php");
if ($_GET['urlx']) )
{
$req =& new HTTP_Request(urldecode($_GET['urlx'])););
if (!PEAR::isError($req->sendRequest()))
{
echo "<script>var y= \"";
echo rawurlencode($req->getResponseBody());
echo "\";";
?>
</script><?php
print_r($req->getResponseCookies());
}
}
?>
Now what does it do. The URL which the proxy.php calls through the HTTP_Request object is passed through it as a GET parameter. In our case the URL would be
proxy.php?urlx=http://www.exampleY.com/testY.php
I have to not URL encode the above line. But before you can actually pass the the URL of the page as the GET parameter you will need to URL Encode it and then obviously URL decode it on the proxy.php. Refer to the article on URL Encode and Decode with JavaScript. For PHP you can just use the funtion urldecode(). The proxy.php will then recieve the response from the page testY.php and echo it. Also the cookies which are returned are also printed. Notice that I have used <script> tag before printing out the response. This I will explain below.
The JavaScript involved
function URLEncode(url) //Function to encode URL.
{
// The Javascript escape and unescape functions do not correspond
// with what browsers actually do...
var SAFECHARS = "0123456789" + // Numeric
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
"abcdefghijklmnopqrstuvwxyz" +
"-_.!~*'()"; // RFC2396 Mark characters
var HEX = "0123456789ABCDEF";
var plaintext = url;
var encoded = "";
for (var i = 0; i < plaintext.length; i++ ) {
var ch = plaintext.charAt(i);
if (ch == " ") {
encoded += "+"; // x-www-urlencoded, rather than %20
} else if (SAFECHARS.indexOf(ch) != -1) {
encoded += ch;
} else {
var charCode = ch.charCodeAt(0);
if (charCode > 255) {
alert( "Unicode Character '"
+ ch
+ "' cannot be encoded using standard URL encoding.\n" +
"(URL encoding only supports 8-bit characters.)\n" +
"A space (+) will be substituted." );
encoded += "+";
} else {
encoded += "%";
encoded += HEX.charAt((charCode >> 4) & 0xF);
encoded += HEX.charAt(charCode & 0xF);
}
}
} // for
return encoded;
};
///////////////////End of URLEncode //////////////////////////
function URLDecode(url) //function decode URL
{
// Replace + with ' '
// Replace %xx with equivalent character
// Put [ERROR] in output if %xx is invalid.
var HEXCHARS = "0123456789ABCDEFabcdef";
var encoded = url;
var plaintext = "";
var i = 0;
while (i < encoded.length) {
var ch = encoded.charAt(i);
if (ch == "+") {
plaintext += " ";
i++;
} else if (ch == "%") {
if (i < (encoded.length-2)
&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
plaintext += unescape( encoded.substr(i,3) );
i += 3;
} else {
alert( 'Bad escape combination near ...' + encoded.substr(i) );
plaintext += "%[ERROR]";
i++;
}
} else {
plaintext += ch;
i++;
}
} // while
return plaintext;
};
////////////////////////End of URLDecode /////////////////////////////////////////
function ajax_reqt(url)
{
var url_post='proxy.php?urlx=' . URLEncode(url);
var oXmlHttp = createXMLHttp();
oXmlHttp.open("get", url_post , true);
oXmlHttp.onreadystatechange = function () {
if (oXmlHttp.readyState == 4)
{
if (oXmlHttp.status == 200)
{
var response ;
response = oXmlHttp.responseText;
var t_st = response.indexOf("<script>");
var t_en = response.indexOf("</script>");
///////This evaluates what is between the <script></script> tag in the response////////////.
eval(response.substring(t_st+8,t_en));
//////////The rest of the string returned from proxy.php contains cookies which are sent to handle_cookies()/////////////
handle_cookies(response.substring(t_en+9,response.length-1));
//////////// The response is now made equal to the response text which is returned from the proxy.php//////
response= URLDecode(y);
/////// Do whatever you need with the variable response. It contains the ajax response/////////
//////// Here I will just alert the response//////
alert("ajax response from exampleY.com/testY.php is " + response );
}
}
}
}
};
oXmlHttp.send();
}
//////////// End of do_post //////////////////////////
function handle_cookies(res)
{
if (res.indexOf("[name]")==-1)
{
return;
}
var st ="";
var en="";
var ck="";
var val="";
var t=1;
while (t==1)
{
st = res.indexOf("[name]");
en = res.indexOf("[value]");
ck = res.substring(st+10,en-13);
res = res.substring(en+11);
en = res.indexOf(")");
val = res.substring(0,en-9);
///// Now the variables ck, val contain the name value pair of each cookie, one a time./////
////// You can choose save these cookies this domain with the document.cookies in javascript//////
////////Or you can discard them. Here I will just alert the name and value of each cookie////////
alert('cookie name = ' + ck + ' and cookie value = ' val);
res = res.substring(en);
if (res.indexOf("[name]") == -1) t=0;
}
}
////////////End of Handle_Cookies//////////////
Ohhk!! Thats a lot of JavaScript. I totally agree, but let me break it up for you. The functions URLEncode and URLDecode, do nothing more than just encode and decode the url which has to be passed as a get parameter (I have explained url encode and decode in another one of my articles: http://www.mabaloo.com/Web-Development/Urlencode-and-Urldecode-with-JavaScript.html).
First lets start by what proxy.php does. Now what actually happens is that proxy.php gets the response from the page examplY.com/testY.php. It then prints this response as a syntax for javascript variable y. After </script> the cookies which are returned from the page are printed.
Something like '<script>y="This is the response";</script>here are the cookies'.
Now all this is passed to the JavaScript of the page which makes the AJAX call. Rest is not that hard its just plain string processing. First the variable y is extracted from the string and eval (eval executes a string as if it were a JavaScript code) is done on it so that we can use variable y as the response. We then URLDecode(y) to get it in readable form. The string that follows the '</script>' is then extracted and sent to the function handle_cookies().
This function extracts the name-value pairs of cookies one by one and make them available for further action.
Ok I know its not that simple, However it works pretty well. I have been using this technique from cross domain communication since a long time. The major drawback that I found was that nothing resembling HTTP Request of PEAR was found in other platforms, stopping this from being a real cross platform solution(if you find out tell me too). Another way of cross domain communication is by using Iframes. I have explained that in one of my articles on cross domain message passing using Iframe.
Quote this article on your site
Only registered users can write comments. Please login or register.
Powered by AkoComment Tweaked Special Edition v.1.4.6 AkoComment © Copyright 2004 by Arthur Konze - www.mamboportal.com. All right reserved |