Cross domain AJAX в плагинах

Cross domain AJAX в плагинах

Недавно мне нужно было написать плагин для браузера Google Chrome. Суть была в анализе активной страницы и получении всевозможной SEO-информации. Под катом я опишу неприятную ситуацию, вызванную кроссдоменным ajax-запросом, а так же листинг кода для получения количества страниц в кеше яндекса для указанного домена.

Одним из пунктов востребованной SEO-информации было количество страниц в кеше яндекса. Плагин писался по-быстрому и после небольшого гугления я понял, что яндекс не предоставляет никакого API по этому поводу. Что же, приходится вручную подбирать адрес страницы, которой можно передать в качестве запроса домен нужного сайта и распарсить количество страниц. Информация очень неточная и округленная, но для общей статистики пойдет, да и суть статьи не в этом. Немного разобравшись с ситуацией, я подобрал нужный URL для POST-запроса: var y_Idx = 'http://yandex. ru/yandsearch? text=&site=http://%URL%&ras=1&site_manually=true';

В тексте я заменил константным выражением %URL% адрес домена, по которому нужно искать информацию. Дальше мы будем заменять это выражение нужной строкой.

Function setYaIndex(url)

{

// Заменяем в адресе константное выражение на активный домен var page = y_Idx. replace('%URL%', url);

$.get(page, function(response) { var res = response. match(/(Нашёлся|Нашлось|Нашлась)(.*?)ответ/); if (res == null) res = '000'; var mp = 1; if (res[2].indexOf('тыс') > 0) mp = 1000; if (res[2].indexOf('млн') > 0) mp = 1000000;

// Результат return parseFloat(res[2]) * mp;

});

}

Парсинг он такой :). Но суть не в этом, с какой же ошибкой я столкнулся?

Cross domain ajax

Для начала объясню суть кроссдоменного аякса. Объект XMLHttpRequest блокирует любые обращения к “левым” доменам в целях безопасности. Есть несколько путей обойти эти ограничения:

Использовать прокси-скрипт (в том случае, если обе стороны: отправляющая и принимающая запрос написаны вами);

Использование Flash;

Использование тега script и его атрибута src.

Подробней о реализациях всего этого можете прочитать на этом сайте.

Политика безопасности в Google Chrome

Разработчики браузера Google Chrome сделали отличный API для расширений. Если вы уже писали их когда-либо, то знаете о существовании manifest. json файла, в котором можно указать некоторые параметры плагина. Среди них есть управление безопасностью, а точнее: адреса/домены, к которым скрипт непосредственно может обращаться. Таким образом мы можем обойти запрет на запрос к “левым” доменам, но с ограниченным списком этих самых доменов. Конечно, ничто не мешает прописать в качестве маски: “http://*/”, но это некрасиво и небезопасно.

Вернемся к плагину, который я создавал. Я прописал в manifest. json вот такой код:

"permissions": [

"tabs",

"http://yandex. ru/*",

"https://yandex. ru/*"

]

В итоге $.get не возвращал результата. Отследив Firebug'ом я понял, что там идет редирект с изменением адреса страницы. Там же я увидел, что меняется домен и к нему добавляются аргументы: lr, ncnrd. Как я понимаю, так яндекс отслеживает пользователей. К сожалению, у меня не сохранились скрины с выводом FireBug'a, где было видно сам факт редиректа и возвращаемую информацию, но было видно, что после первого редиректа (а до этого все шло отлично) вдруг обрывается какая-либо связь.

К сожалению, я немало времени потратил на выяснение причины того, что после редиректа блокируется дальнейшее выполнение: ведь в политике безопасности был прописан адрес яндекса, да и первый запрос проходил удачно.

Причина ошибки

А разгадка проста. Если читатель внимательный, он ещё мог заметить это на первом скрине. Я живу в Украине, поэтому яндекс автоматически обнаруживает мой регион и перенаправляет на украинский домен яндекса. В итоге, первый запрос шел к ru-домену, а редирект пересылал второй запрос на ua-домен.

Как вы могли бы догадаться, чтобы решить проблему нужно изменить маску в manifest. json на http://yandex.*/*. Будьте внимательны!


Карта сайта


Информационный сайт Webavtocat.ru