Замена междоменного запроса с помощью JavaScript - PullRequest
2 голосов
/ 16 декабря 2010

У меня есть JavaScript на сервере с именем kopernikus.science.net, который хочет получить доступ к файлу на другом сервере с именем galileo.science.net.Вот забавный пример того, что я имею в виду:

code residing on  http://kopernikus.science.net/makecalendar.js :

    var request = new XMLHttpRequest();
    request.open("GET","galileo.science.net/calendar", false);
    request.send(null);
    document.getElementById("calendar").innerHTML =
        "<div>" + request.responseText.split('\n')[0] + "</div>";

К сожалению, из-за «одинаковой политики происхождения» современных веб-браузеров скрипту запрещен доступ к данным в другом домене.

Конечно, мой вопрос:

Как я могу получить доступ к удаленному файлу в любом случае?

Допускаются решения вне JavaScript, такие как зеркальное отображение файла или настройка .htaccess.Какие у меня варианты?Какие из них требуют наименьшего количества разрешений на веб-сервере?

Данный файл представляет собой календарь в формате vcalendar, который регулярно меняется.Я на общем хосте и у меня нет прав sysadmin, но я могу запускать сценарии PHP и CGI и изменять некоторые части файла .htaccess.

Ответы [ 5 ]

8 голосов
/ 16 декабря 2010

Некоторые параметры:

  1. Если вы управляете серверами и ваши пользователи будут использовать современный веб-браузер, вы можете использовать CORS .К сожалению, в IE7 и ниже отсутствует поддержка CORS.В IE8 он есть, но вы должны использовать XDomainRequest вместо XMLHttpRequest (другие браузеры, такие как Chrome и Firefox, обрабатывают CORS полностью прозрачно с XMLHttpRequest).
  2. Если нет, вы можете использовать JSONP , который работает со всеми браузерами.
  3. Вы можете использовать document.domain, чтобы указать, что обе эти страницы (если онидействительно субдомены одного и того же science.net домена) имеют одинаковое происхождение.Это хорошо работает во всех браузерах, но имеет тот недостаток, что вам сначала нужно загрузить целевой документ в окно (возможно, скрытый iframe), прежде чем вы сможете получить к нему доступ, потому что целевой документ также должен установить document.domain (чтобы показать, что он хочет сотрудничать с вами).
  4. Еще одна альтернатива для публичных вещей - использование YQL в качестве прокси .
  5. Если все этитерпеть неудачу, ваш единственный реальный вариант - иметь прокси-скрипт на вашем сервере, который вы запрашиваете, который затем использует код на стороне сервера для запроса ресурса из другого домена (так как это ограничение применяется только на стороне клиента).

Они перечислены примерно в том порядке, в котором я бы их использовал.Например, используйте CORS, если вы управляете серверами и знаете, что ваши клиенты будут использовать современные браузеры;если нет, посмотрите на JSONP (хотя из вашего комментария ниже вы, вероятно, не сможете);если не один из них, возможно, document.domain является ответом;и т. д. и т. д., работая по списку до последней инстанции (проксирование).

1 голос
/ 16 декабря 2010

Если вы можете развернуть PHP на kopernikus.science.net, почему бы просто не прокси его там ...

<?php
header('Content-Type: application/x-javascript');
print file_get_contents('http://galileo.science.net/calendar');

(и, конечно, вы могли бы кратко его кэшировать на прокси и клиенте, чтобы уменьшить сетевой шум)

Обновление

Если вы хотите кешировать ....

<?php
header('Content-Type: application/x-javascript');
define("CACHEDIR", '/tmp/webcache/');
$cache_time=14 * 24 * 60 * 60; // cache for 2 weeks
$key=sha1('http://galileo.science.net/calendar');

if (@filemtime(CACHEDIR . $key) > time() - $cache_time) { // cache good
    print file_get_contents(CACHEDIR . $key);
} else {  // cache stale
    $freshcopy=file_get_contents('http://galileo.science.net/calendar');
    print $freshcopy;
    if (!file_put_contents(CACHEDIR . $key, $freshcopy)) {
       // report a problem writing files
    }
}
1 голос
/ 16 декабря 2010

К сожалению, из-за "того же происхождения" политика "современных веб-браузеров, Сценарий запрещен доступ к данные в другом домене.

Но то, что вы можете сделать, это использовать json-p .

Сценарии и запросы JSONP не являются при условии соблюдения той же политики происхождения ограничения.

<!DOCTYPE html>
<html>
<head>
  <style>img{ height: 100px; float: left; }</style>
  <script src="http://code.jquery.com/jquery-1.4.4.js"></script>
</head>
<body>
  <div id="images">

</div>
<script>
$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
  {
    tags: "cat",
    tagmode: "any",
    format: "json"
  },
  function(data) {
    $.each(data.items, function(i,item){
      $("<img/>").attr("src", item.media.m).appendTo("#images");
      if ( i == 3 ) return false;
    });
  });</script>

</body>
</html>

В качестве дополнительного примечания поддержка современных браузеров CORS (Internet Explorer 8+, Firefox 3.5+, Safari 4+ и Chrome).

0 голосов
/ 16 декабря 2010

Это очень известная проблема, и JSONP - это решение проблемы. Вы можете Google и штраф тонны информации об этом. Вы можете рассмотреть это как пример использования JSONP с и без jQuery.

http://www.beletsky.net/2010/07/json-jsonp-and-same-origin-policy-issue.html

0 голосов
/ 16 декабря 2010

Использование JSONP . В javascript, вставьте новый элемент сценария на страницу, которая имеет интерфейс другого сервера в качестве источника.

Сервер должен вернуть что-то вроде этого:

callCallback({"some":"JSONString"});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...