Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 15.09.2012, 02:42
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Кроссдоменные запросы во всех браузерах
Снова привет всем!

Хочу представить вам новую свою наработку, собственно обмен данными между разными доменами.

Ни для кого не секрет что давно существуют методы для обмена данными между разными доменами. Один из этих вариантов является официальным и описывается в спецификациях XMLHttpRequest level 2 где есть возможность обмениваться данными между разными доменами, при этом сайт на другом домене не обязательно должен быть у вас во фрейме. Для этого удаленный сервер должен отослать заголовок к примеру "Access-Control-Allow-Origin: *". Который разрешит браузеру взять данные и отдать их вашему скрипту.

Для ИЕ8-9 есть специальный метод для обмена данными между разными доменами называется он XDomainRequest, к сожалению майкрософт не особо заботится о разработчиках и всегда борется с вирусами в своих наработках. От того их метод имеет массу ограничений, хотя и не лишен возможностью обмениваться данными, но заставляет на стороне сервера, немного попотеть. Например отправка POST данных с помощью их метода, заставляет на стороне сервера, пришедшие RAW-данные обрабатывать самостоятельно, это ограничение вызвано тем что при запросе XDomainRequest не отправляет серверу заголовков о типе данных, такие как:
Content-Type: application/x-www-form-urlencoded
или
Content-Type: multipart/form-data
от того сервер просто не знает что делать с данными, и просто их складирует в переменную:
$HTTP_RAW_POST_DATA
- это если вы юзаете PHP.

Не смотря на это ограничение, многие разработчики не теряют оптимизма творить. И продолжают работать с тем что им дают.

Вот для примера код который работает во всех современных браузерах и включая ИЕ8+
var xhr = ( window.XMLHttpRequest && "withCredentials" in (new XMLHttpRequest) ) ?
        new XMLHttpRequest : window.XDomainRequest ? new XDomainRequest : null;

if ( xhr ) {
    xhr.open( "GET", "http://history.spb-piksel.ru/", false );
    xhr.onload = function() {
        alert( this.responseText ); // тут увидите HTML-code моего сайта
    }
    xhr.onerror = function() {
        alert( "Не удалось сделать запрос" );
    }
    xhr.send( null );
} else {
    alert( "Извините но ваш браузер не поддерживает Кроссдоменные запросы." );
}
Я решил сделать возможность что бы данный код продолжал работать и в старых браузерах, для этого я начал для ИЕ7 писать метод XDomainRequest, после того как написал. Решил его проверить и в старых браузерах, таких как Opera, FireFox которые еще не поддерживали XMLHttpRequest level 2. Как оказалось, моя разработка так же работает и в них.

Теперь подключаем мою библиотеку:
<script type="text/javascript" src="http://code.spb-piksel.ru/light.core.class.min.js"></script>
<script type="text/javascript" src="http://code.spb-piksel.ru/XDomainRequest.min.js"></script>
<script type="text/javascript">

// а вот и наш код:

var xhr = ( window.XMLHttpRequest && "withCredentials" in (new XMLHttpRequest) ) ?
        new XMLHttpRequest : window.XDomainRequest ? new XDomainRequest : null;

if ( xhr ) {
    xhr.open( "GET", "http://history.spb-piksel.ru/", false );
    xhr.onload = function() {
        alert( this.responseText ); // тут увидите HTML-code моего сайта
    }
    xhr.onerror = function() {
        alert( "Не удалось сделать запрос" );
    }
    xhr.send( null );
} else {
    alert( "Извините но ваш браузер не поддерживает Кроссдоменные запросы." );
}
</script>
Теперь этот код работает во всех браузерах...

А теперь самое главное, на стороне удаленного сервера так же нужно внести изменения. Что бы метод полноценно работал. Для обычного стандартного XMLHttpRequest и для XDomainRequest сервер должен отправить заголовок PHP:
<?php
	/*
	* Разрешим получать данные через XMLHttpRequest, XDomainRequest (JavaScript)
	*/
	header( "Access-Control-Allow-Origin: *" );
?>
для моего метода нужно добавить дополнительный код, который нужно написать сразу же после того как вы отправите все заголовки браузеру:
<?php
	/*
	* Разрешим получать данные через XMLHttpRequest, XDomainRequest (JavaScript)
	*/
	header( "Access-Control-Allow-Origin: *" );

	/*
	* Разрешим получать данные через shim-XDomainRequest (JavaScript)
	*/
	if (
		!empty( $_GET['Access-Control-Allow-Origin'] ) &&
		preg_match( "/^https?:\/\/[\S]/i", $_GET['Access-Control-Allow-Origin'] )
	) {
		echo "<script>".(isset($_SERVER['HTTP_REFERER'])&&$_GET['Access-Control-Allow-Origin']===$_SERVER['HTTP_REFERER']?1:
			"window.name==='".$_GET['Access-Control-Allow-Origin']."'")."&&(window.onload=function(){window.name=document.".
			"documentElement.innerHTML;window.history.back();})</script><plaintext>>";
		unset( $_GET['Access-Control-Allow-Origin'] );
	}


	// тут уже пишите остальной ваш PHP код, обработчики POST и т.д.
?>
Как видите, в браузер происходит вывод дополнительного скрипта, в самом начале кода, который копирует в переменную window.name все данные, что бы потом их оттуда прочитать.

Вот собственно и вся наработка. С большим удовольствием выслушаю вашу критику и предложения)))

Всем спасибо!

Скачать скрипты:
http://code.spb-piksel.ru/light.core.class.js или https://github.com/devote/jsClasses
http://code.spb-piksel.ru/XDomainRequest.js на гитхаб пока не выкладывал

Последний раз редактировалось devote, 18.09.2012 в 12:43.
Ответить с цитированием
  #2 (permalink)  
Старый 16.05.2014, 08:55
Интересующийся
Отправить личное сообщение для Ol'kO Посмотреть профиль Найти все сообщения от Ol'kO
 
Регистрация: 14.08.2013
Сообщений: 14

Спасибо! Очень нужная и полезная статья, особенно для не очень разбирающихся в AJAX. Мне она очень помогла!
Ответить с цитированием
  #3 (permalink)  
Старый 16.05.2014, 12:36
что-то знаю
Отправить личное сообщение для devote Посмотреть профиль Найти все сообщения от devote
 
Регистрация: 24.05.2009
Сообщений: 5,176

Сообщение от Ol'kO Посмотреть сообщение
Мне она очень помогла!
Рад что хоть кому то угодил этим постом)
__________________
хм Russians say завтра but завтра doesn't mean "tomorrow" it just means "not today."
HTML5 history API рассширение для браузеров не поддерживающих pushState, replaceState
QSA CSS3 Selector Engine
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Кроссдоменные запросы aze AJAX и COMET 1 27.01.2012 02:43
Скрипт работает во всех браузерах кроме IE (getElementById) cmd Internet Explorer 9 19.03.2011 16:06
Код работает корректно во всех браузерах кроме IE8 Yamasa Events/DOM/Window 6 18.01.2011 07:40
getElementById - не работоспособность во всех браузерах malkolm Firefox/Mozilla 2 20.06.2010 13:04
Скрипт не работает во всех браузерах, кроме Оперы Yadooumne! Элементы интерфейса 6 27.10.2008 17:08