Как сделать ajax-запрос на другой домен?

Вчера по долгу службы пришлось разбираться с кросс-доменными ajax-запросами. Суть проблемы была в следующем: мне нужно было, чтобы мой скрипт отправлял с нескольких сайтов запросы на один сервер, собирающий некоторые данные. Политика безопасности браузеров запрещает это делать через обычный XHTTPRequest.

Погуглив и проведя ряд экспериментов у меня получилось вот что.

Примечание: Ниже я приведу готовое решение. А для желающих обрести теоретическую подкованность, предлагаю к прочтению:

Итак, для отправки запросов я воспользуюсь библиотекой jQuery. С версии 1.2 эта библиотека поддерживает JSONP нативно. Вот, собственно сам код для выполнения запроса:

$.getJSON("http://server.ru/logger.php?callback=?", function(data){
    // тут обрабатываем полученные данные
});

Обратите внимание на параметр «callback=?» в адресе, на который отправляется запрос. Вместо вопроса jquery подставит название callback-функции. Эта callback-функция будет вызвана при получении ответа от сервера. Учтем это в серверной части.

<?php
    echo $_GET['callback']."({param1:'value',param2:0});";
?>

Т.е. выход скрипта должен генерировать не просто JSON, а вызов callback-функции и передачей ей параметров, которые нужно передать от сервера клиенту.

Вот, собственно и вся премудрость. Если возникнут вопросы, задавайте в комментариях, я постараюсь на них ответить


 

Похожие записи

Эта запись опубликована в рубриках: javascript. Метки записи: , , . Постоянная ссылка.

19 комментариев Как сделать ajax-запрос на другой домен?

  1. Bercut пишет:

    не работает в IE6 из-за ошибки в библиотеке jQuery

  2. Лобач Олег пишет:

    А версия библиотеки какая?

  3. poRAmidol пишет:

    Спасибо, а IE6 идет лесом пусть ;-))

  4. omagicall пишет:

    А у меня возникает ошибка «invalid label», причем использование функции eval проблему не решает...

    • Лобач Олег пишет:

      Эм... а поподробней?

      • omagicall пишет:

        На своем одном сайте мне необходимо получить данные с другого.

        Код следующий:

        $(document).ready(function() { 
                $.getJSON('http://mysite.ru/test.php?callback=?', function(json) { 
                    $("div#result").html(json.qwer); 
                }); 
        });

        test.php

        $arr = array ("qwer"=&gt;"test_json_respons"); 
        echo json_encode($arr);

        Но при получении ответа возникает ошибка: Firebug пишет 'Invalid Label'. и потом мою json-строку.

        Причем это происходит только если посылать запрос на другой домен (используя '?callback=?') ,

        Если test.php использовть на этом же домене (т.е. $.getJSON ('test.php', function (json) {...}) ошибки не возникает.

        Чтоб прочистить json -данные использовала функцию eval:

        var response = eval ( '(' + json + ')' );

        $(«div#result»).html (response.qwer);

        но это не дало никакого результата.

        • Лобач Олег пишет:

          А если в test.php написать следующее:

          <?php
          $arr = array («qwer»=>"test_json_respons");
          echo $_GET['callback'].json_encode ($arr);
          ?>

          • omagicall пишет:

            Тогда возникает ошибка : «missing ; before statement» — потому что дальше выводится строка jsonp137773236376{"qwer":"test_json_respons"}

            • Лобач Олег пишет:

              Прошу прощения, поторопился немного.

              Вот правильный вариант:

              <?php
                  $arr = array («qwer»=>"test_json_respons");
                  echo $_GET['callback'].'('.json_encode ($arr).');';
              ?>

              • omagicall пишет:

                Спасибо! так работает нормельно)

                Но это для тестирования...

                а на практике мне требуется отправить запрос на другой сайт, от которого данные приходят в формате json, т.е. могу ли я на своем сайте уже обработать готовый json-ответ? т.е. непосредственно не правя ничего в test.php?

                • Лобач Олег пишет:

                  Видимо тут без скрипта-прокси не обойтись, т.к. политика безопастности запрещает запросы на «чужие» домены. Если есть возможность модифицировать ответ сайта-источника или у него есть поддержка JSONP, то можно воспользоваться JSONP. Иначе придется данные получать скриптом на сервере, а затем отдавать клиенту Вашего сайта.

      • omagicall пишет:

        На своем одном сайте мне необходимо получить данные с другого.

        Но при получении ответа возникает ошибка: Firebug пишет 'Invalid Label'. и потом мою json-строку.

        Причем это происходит только если посылать запрос на другой домен (используя '?callback=?') ,

        Если test.php использовть на этом же домене (т.е. $.getJSON ('test.php', function (json) {...}) ошибки не возникает.

        Чтоб прочистить json -данные пробовала использовать функцию eval:

        var response = eval ( '(' + json + ')' );

        $(«div#result»).html (response.qwer);

        но это не дало никакого результата.

  5. Павел М. пишет:

    Спасибо за наводку! Сам бы не додумался.

    Вот может кому пригодится для копипасты:

    function printResult($results) {
        $resultsArr = array();
        foreach($results as $resultKey => $resultVal) {
            $resultsArr[] = "$resultKey:'$resultVal'";
        }
        $resultsStr = join(',', $resultsArr);
        echo $_GET['callback']."({".$resultsStr."});";
        exit();
    }
    
    printResult(array('msg' => 'Some msg', 'result' => '42'));

  6. Александр пишет:

    Данная инфа очень полезна. Спасибо!

  7. fenuk пишет:

    а что делать в случае, если необходимо отправить POST запрос?

    • Лобач Олег пишет:

      На сколько я помню, принципиальной разницы между GET-ом и POST-ом для этого механизма нет. Разница в том, что для GET-а есть готовый метод, а для POST-а его нет (хотя в этом не уверен, надо в документации посмотреть, возможно есть параметр типа запроса).

      Смысл метода заключается в передаче на сервер имене callback-функции. Ответом сервера является JS-код — вызов callback-функции с результатами работы сервера в качестве входного параметра.

Оставить комментарий

Почта (не публикуется) Обязательные поля помечены *

*

Вы можете использовать эти HTML теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>