Winner Code
Veni, vidi, programmare!
Veni, vidi, programmare!
24 июля 2011
Недавно мне нужно было написать плагин для браузера 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; }); }
Парсинг он такой :). Но суть не в этом, с какой же ошибкой я столкнулся?
Для начала объясню суть кроссдоменного аякса. Объект XMLHttpRequest блокирует любые обращения к “левым” доменам в целях безопасности. Есть несколько путей обойти эти ограничения:
Подробней о реализациях всего этого можете прочитать на этом сайте.
Разработчики браузера 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.*/*. Будьте внимательны!