Cross Domain XMLHttpRequest

    An important component of AJAX technology is XMLHttpRequest. This object makes it possible to make HTTP requests to the server without the need to reload the page.

    Typically, working with XMLHttpRequest is as follows:
    1. Creating an instance of the XMLHttpRequest object
    2. Installing an event handler that occurs when the state of the object changes (onreadystatechange)
    3. Opening a connection (open) and sending a request (send)

    Unfortunately, XMLHttpRequest only works with files that are in the same domain as the page using the XMLHttpRequest. That is, a request can only be made to addresses with the same domain, protocol and port as the current page. This is done for security reasons and creates problems if you need to get data / content from another site.

    Recently, this problem appeared in front of me, a very simple solution was chosen, which will be discussed later.

    Proxying! A simple and intuitive method for cross-domain queries. The essence of the method is as follows:

    1. XMLHttpRequest accesses the PHP script on its domain, passing it the request method, address and parameters
    2. The PHP script, in turn, acts as a proxy. That is, it carries out the request based on the parameters passed to it and returns the response of another server to the JS script. The

    operation of the PHP script, which is a proxy for a cross-domain request, is based on CURL.

    Here is the proxy.php script itself: XMLHttpRequest accesses it and passes 3 parameters: 1. method - 1 for a GET request and 2 for POST 2. url - request address 3. params - request parameters PHP script checks for input parameters, checks for allowed whether to send a request to url (an array of regexp $ allowed) and actually sends a request and returns a response from the remote server. From JS, this PHP script is used like this:
    header("Content-Type: text/xml; charset=windows-1251");
    // параметры запроса
    $method = (empty($_GET['method'])) ? 1 : $_GET['method'];
    $url = $_GET['url'];
    $url = (empty($_GET['url'])) ? die("no url") : $_GET['url'];
    $params = $_GET['params'];
    // проверим целевой домен запроса
    $allowed = array(1 => "~http:\/\/(www\.)?habrahabr\.ru\/~", 2 => "~http:\/\/(www\.)?el\-egoisto\.com\/~");
    $count = count($allowed);
    for ($i = 1; $i <= $count; $i++)
    {
    if (preg_match($allowed[$i],$url))
    {
    // домен в списке разрешенных - отправляем запрос
    $ch = curl_init();
    switch ($method)
    {
    case 1:
    // GET запрос
    curl_setopt($ch, CURLOPT_URL, $url."?".$params);
    break;
    case 2:
    // POST запрос
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    break;
    }
    curl_setopt($ch, CURLOPT_HEADER, 0);
    $response = curl_exec($ch);
    $header_size = curl_getinfo($ch,CURLINFO_HEADER_SIZE);
    $xml = substr($response,$header_size);
    echo $xml;
    curl_close($ch);
    exit();
    }
    }
    ?>










    There are 2 functions for working with XMLHttpRequest - CreateReq and GetData. The first one creates an instance of the object, and the second one sets up a handler and sends a request. Let's consider sending a GET request using the example of getting karma and strength from Habr :) GetHabraMe will send a GET request to habrahabr.ru/api/profile/lordeg using proxy.php and the result will be returned to the element with id “data”. Sending a POST request is almost the same: Implementation in "combat conditions" can be found here - lord-phoenix.com (links "current music" and "habralordeg") :) I do not pretend to be original, I just decided to draw up a solution to the problem that appeared before me , in the form of a blog topic. Maybe someone will benefit from my experience. Related materials:
    function CreateReq()
    {
    var req = null;
    if (window.XMLHttpRequest)
    {
    try
    {
    req = new XMLHttpRequest();
    }
    catch(e)
    {
    req = null;
    }
    }
    else if (window.ActiveXObject)
    {
    try
    {
    req = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch(e)
    {
    try
    {
    req = new ActiveXObject("Microsoft.XMLHTTP");
    }
    catch(e)
    {
    req = null;
    }
    }
    }
    return req;
    }

    function GetData(url,callback)
    {
    req = new CreateReq;

    if(req != null)
    {
    req.onreadystatechange = callback;
    req.open('GET', url, true);
    req.send(null);
    }
    else alert("Произошла ошибка..");
    }




    function GetHabraMe()
    {
    GetData("/proxy.php?method=1&url="+encodeURIComponent("http://habrahabr.ru/api/profile/lordeg"),GetHabraCallback);
    }

    function GetHabraCallback()
    {
    if(req.readyState == 4)
    {
    if(req.status == 200)
    {
    var xmlDoc = req.responseXML;
    var karma = xmlDoc.getElementsByTagName("karma").item(0).firstChild.data;
    var rating = xmlDoc.getElementsByTagName("rating").item(0).firstChild.data;
    var place = document.getElementById("data");
    if(place != null)
    {
    place.innerHTML = "Карма: "+karma+"
    Рейтинг: "+rating+";
    }
    }
    }
    return false;
    }






    function GetPings()
    {
    var d_topic = document.getElementById("topic");
    if (d_topic.innerHTML == "Последние треки")
    {
    GetData("/proxy.php?method=2&url="+encodeURIComponent("http://el-egoisto.com/frontend.php")+"¶ms="+encodeURIComponent("func=recent&owner=9&id=1&cutoff=48"),GetMyLastPingsCallback);
    }
    }





    1. xmlhttprequest.ru
    2. ru.wikipedia.org/wiki/XMLHttpRequest
    3. ru.wikipedia.org/wiki/AJAX
    4. ru.wikipedia.org/wiki/CURL

    Also popular now: