Я хотел бы сделать wiki сообщества относительно HTML/JS политик одинакового происхождения, чтобы, надеюсь, помочь любому, кто ищет эту тему. Это одна из самых популярных тем для SO, и для нее нет консолидированной вики, поэтому я иду:)
Такая же политика происхождения предотвращает документ или script, загруженный из одного происхождение от получения или установки свойства документа от другого происхождение. Эта политика датируется полностью вернуться к Netscape Navigator 2.0.
Пожалуйста, держите примеры подробными и желательно также связывать свои источники.
document.domain
Обратите внимание, что это метод iframe, который устанавливает значение document.domain в суффикс текущего домена. Если это так, более короткий домен используется для последующих проверок происхождения. Например, предположим, что script в документе в http://store.company.com/dir/other.html
выполняет следующее утверждение:
document.domain = "company.com";
После выполнения этого утверждения страница проведет проверку происхождения с помощью http://company.com/dir/page.html
. Однако по тем же соображениям company.com не может установить document.domain
в othercompany.com
.
С помощью этого метода вам будет разрешено вызывать javascript из iframe, полученного на субдомене на странице, полученной в основном домене. Этот метод не подходит для междоменных ресурсов, поскольку такие браузеры, как Firefox, не позволят вам изменить document.domain
на полностью чуждый домен.
Источник: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
Совместное использование ресурсов для разных источников (CORS) - это рабочий проект W3C, который определяет, как браузер и сервер должны взаимодействовать при доступе к источникам через источник, Основная идея CORS заключается в использовании пользовательских HTTP-заголовков, позволяющих обозревателю и серверу достаточно знать друг друга, чтобы определить, будет ли запрос или ответ успешным или неудачным.
Для простого запроса, который использует либо GET
, либо POST
без пользовательских заголовков и чье тело text/plain
, запрос отправляется с дополнительным заголовком Origin
. Заголовок Origin содержит начало (протокол, имя домена и порт) запрашивающей страницы, чтобы сервер мог легко определить, должен ли он отвечать на ответ. Пример Origin
заголовок может выглядеть следующим образом:
Origin: http://www.stackoverflow.com
Если сервер решает, что запрос должен быть разрешен, он отправляет заголовок Access-Control-Allow-Origin
, эхо возвращающий тот же исходный код, который был отправлен, или *
, если это общедоступный ресурс. Например:
Access-Control-Allow-Origin: http://www.stackoverflow.com
Если этот заголовок отсутствует или исходное имя не совпадает, браузер не разрешает запрос. Если все хорошо, браузер обрабатывает запрос. Обратите внимание, что ни запросы, ни ответы не содержат информацию о файлах cookie.
Команда Mozilla предлагает в их сообщение о CORS, что вы должны проверить наличие свойства withCredentials
, чтобы определить, является ли браузер поддерживает CORS через XHR. Затем вы можете связать с существованием объекта XDomainRequest
для охвата всех браузеров:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Обратите внимание, что для работы метода CORS вам необходимо иметь доступ к любому типу обработчика заголовков сервера и не может просто обращаться к любому стороннему ресурсу.
Источник: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
window.postMessage
window.postMessage
при вызове вызывает отправку MessageEvent
в целевом окне, когда все ожидающие завершения функции script завершаются (например, оставшиеся обработчики событий, если window.postMessage
вызывается из обработчика события, ранее -set ожидания ожидания и т.д.). MessageEvent
имеет сообщение типа, свойство data
, которое устанавливается в строковое значение первого аргумента, предоставленного в window.postMessage
, свойство Origin
, соответствующее началу основного документа в окне, вызывающем window.postMessage
в момент времени window.postMessage
и свойство source
, которое является окном, из которого вызывается window.postMessage
.
Чтобы использовать window.postMessage
, необходимо подключить прослушиватель событий:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
И должна быть объявлена функция receiveMessage
:
function receiveMessage(event)
{
// do something with event.data;
}
Офлайн-iframe должен также правильно отправлять события через postMessage
:
<script>window.parent.postMessage('foo','*')</script>
Любое окно может получить доступ к этому методу в любом другом окне в любое время, независимо от местоположения документа в окне, для отправки ему сообщения. Следовательно, любой прослушиватель событий, используемый для приема сообщений, должен сначала проверить личность отправителя сообщения, используя исходные и, возможно, исходные свойства. Это нельзя недооценивать: Невозможность проверить свойства Origin
и, возможно, source
, позволяет атаковать сценарии межсайтового сценария.
Источник: https://developer.mozilla.org/en/DOM/window.postMessage
Настройка простого обратного прокси-сервера на сервере позволит браузеру использовать относительные пути для запросов Ajax, в то время как сервер будет действовать как прокси-сервер в любом удаленном месте.
При использовании mod_proxy в Apache основной директивой конфигурации для настройки обратного прокси является ProxyPass
. Он обычно используется следующим образом:
ProxyPass /ajax/ http://other-domain.com/ajax/
В этом случае браузер сможет запросить /ajax/web_service.xml
как относительный URL-адрес, но сервер будет обслуживать это, действуя как прокси-сервер для http://other-domain.com/ajax/web_service.xml
.
Одна интересная особенность этого метода заключается в том, что обратный прокси-сервер может легко распространять запросы на несколько обратных контентов, действуя как балансировка нагрузки.
Я использую JSONP.
В принципе, вы добавляете
<script src="/someData.js"/>
на вашей странице.
some_func() следует вызвать, чтобы вы получили уведомление о том, что данные находятся.
AnyOrigin не работал с некоторыми сайтами https, поэтому я просто написал альтернативу с открытым исходным кодом, называемую whateverorigin.org, которая, кажется, хорошо работает с https.
Я не могу претендовать на кредит для этого изображения, но он соответствует всему, что я знаю по этому вопросу, и предлагает немного юмора в то же время.
Самый последний способ преодоления той же политики, что и я, - http://anyorigin.com/
Сайт создан так, что вы просто даете ему какой-либо url, и он генерирует код javascript/jquery для вас, который позволяет вам получить html/data, независимо от его происхождения. Другими словами, он делает любой URL-адрес или веб-страницу запросом JSONP.
Я нашел его довольно полезным:)
Вот пример javascript-кода от anyorigin:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});
На ум приходит JSONP:
JSONP или "JSON с заполнением" - это дополнение к базовым данным JSON формат, шаблон использования, который позволяет страницу для запроса и более значимо используйте JSON с сервера, отличного от первичный сервер. JSONP - это альтернатива более позднему методу называется совместным использованием ресурсов Cross-Origin.
Проанализируйте в целом то, что доступно там: http://www.slideshare.net/SlexAxton/breaking-the-cross-domain-barrier
Для решения postMessage взгляните на:
и немного отличающаяся версия:
Вот некоторые обходные пути и объяснение политики одного и того же происхождения:
Thiru Blog - обозреватель обходной политики обозревателя обозревателя
Ну, я использовал curl в PHP, чтобы обойти это. У меня есть веб-служба, работающая на порту 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Вот javascript, который вызывает вызов файла PHP
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
Мой HTML работает на WAMP в порту 80. Итак, мы идем, одна и та же политика происхождения была обойдена: -)
Лично window.postMessage
- самый надежный способ, который я нашел для современных браузеров. Вам нужно сделать немного больше работы, чтобы убедиться, что вы не оставляете себя открытым для атак XSS, но это разумный компромисс.
Существует также несколько плагинов для популярных инструментов Javascript, которые включают window.postMessage
, которые предоставляют аналогичную функциональность старым браузерам, используя другие методы, описанные выше.