Доброго времени суток, уважаемые хабражители.
Сегодня мы поговорим подробней об упоминавшейся вскольз технологии написания кроссбраузерных юзерскриптов, а именно об упаковывании юзерскрипта в простейшее расширение для Google Chrome.
Ниже я постараюсь овтетить на вопросы «зачем ?» и «как ?».
Как вы помните, браузер Google Chrome поддерживает скрипты нативно (без необходимости установки сторонних компонентов). Поддержка скриптов реализована на довольно хорошем уровне, но есть одно НО: разработчики Google Chrome пекутся о нашей безопасности и ограничивают всё, что можно ограничить.
В виду этих ограничений нетривиальные скрипты приходится оборачивать в расширение.
Самые главные ограничения:
Указанные выше три ограничения не могут быть сэмулированы и окостылены. Придётся упаковывать юзерскрипт.
Если говорить строго, то на выходе мы получим расширение, а не юзерскрипт. Но учитывая, что:
я позволяю себе говорить о юзерскрипте.
Простое расширение состоит из:
Данный файл описывает расширение: права, составляющие ресурсы, метод запуска и т.д.
Как видно из названия, вся конфигурация представляет собой json-объект.
Подробнее об этом файле можно почитать в официальном доке.
Я рассмотрю необходимый минимум для превращения юзерскрипта в расширение:
Фоновая страница представляет собой обычную html страницу, которая загружается в «невидимый таб» при запуске расширения и работает в фоне в течение всего жизненного цикла расширения.
Ограничения безопасности фоновой страницы настраиваются через параметр permissions в файле-манифесте. Именно через фоновую страницу обходятся ограничения юзерскриптов. Фоновая страница для упакованных юзерскриптов представляет собой proxy, который может «общаться» с юзерскриптом посредством chrome.extension api (Описание).
С теорией покончим, времятусоваться практики!
Рассмотрим подробнее проксирование кроссдоменных запросов из юзерскрипта.
Код background.html:
Код с английскими комментариями доступен на pastebin.com
Вызов из юзерскрипта:
Этот метод работает в Google Chrome. Кроссдоменные запросы из юзерскриптов в других браузерах мы рассмотрим в одной из следующих статей.
Для сборки расширения нам понадобится:
Для тестирования мы можем установить распакованное расширение (спасибо theOnlyBoy за наводку). Вместо упаковки (пункт 3) жмём «Установить распакованное расширение».
В итоге наше расширение установится как и обычное упакованное (плюс будет милая и удобная ссылочка Reload для перезагрузки расширения, см. скриншот).
На этом на сегодня всё, оставайтесь с нами!
Жду вопросы, критику и обсуждения в комментариях.
Список статей:
Сегодня мы поговорим подробней об упоминавшейся вскольз технологии написания кроссбраузерных юзерскриптов, а именно об упаковывании юзерскрипта в простейшее расширение для Google Chrome.
Ниже я постараюсь овтетить на вопросы «зачем ?» и «как ?».
Прелюдия
Как вы помните, браузер Google Chrome поддерживает скрипты нативно (без необходимости установки сторонних компонентов). Поддержка скриптов реализована на довольно хорошем уровне, но есть одно НО: разработчики Google Chrome пекутся о нашей безопасности и ограничивают всё, что можно ограничить.
В виду этих ограничений нетривиальные скрипты приходится оборачивать в расширение.
Какие ограничения?
Самые главные ограничения:
- Скрипт должен делать кроссдоменные запросы
- Скрипту нужен доступ к window.frames[i]
- Скрипту нужны повышенные лимиты localStorage
- И т.д.
Указанные выше три ограничения не могут быть сэмулированы и окостылены. Придётся упаковывать юзерскрипт.
Что получаем на выходе?
Если говорить строго, то на выходе мы получим расширение, а не юзерскрипт. Но учитывая, что:
- процессы установки и управления юзерскрипта и расширения одинаковы;
- юзерскрипты при установке автоматически оборачиваются в расширение;
- обёртка создаётся один раз, а далее мы разрабатываем только сам юзерскрипт;
я позволяю себе говорить о юзерскрипте.
Упаковка
Простое расширение состоит из:
- Файла описания manifest.json
- Фоновой страницы background.html
- Файла юзерскрипта
manifest.json
Данный файл описывает расширение: права, составляющие ресурсы, метод запуска и т.д.
Как видно из названия, вся конфигурация представляет собой json-объект.
Подробнее об этом файле можно почитать в официальном доке.
Я рассмотрю необходимый минимум для превращения юзерскрипта в расширение:
{
"background_page" : "background.html",
"content_scripts" : [
{
"js":[ "my.user.js" ],
"matches":[ "http://*/*" ],
"run_at":"document_end"
}
],
"description" : "",
"name" : "My Userscript",
"permissions" : [ "http://*/*", "unlimitedStorage"],
"version" : "1.3.0"
}
Параметр | Назначение | Комментарий |
---|---|---|
background_page | Определяет файл фоновой страницы | Назначение см. ниже |
content_scripts | Секция подключения контент-скриптов | Именно сюда прописывается информация о нашем юзерскрипте |
js | Массив, содержащий название файлов контент-скриптов | Здесь указывается название нашего единственного скрипта |
matches | Массив, содержащий url-маски для запуска скриптов | Каждый элемент массива соответствует по индексу элементу массива контент-скриптов. Этот параметр определяет, на каких страницах будут запускаться соответствующие скрипты. В нашем случае маска указывает на то, что скрипт запускается на всех страницах, доступных по http. |
run_at | Порядок запуска контент-скриптов | document_end означает, что скрипт будет запускаться после построения DOM-дерева |
description | Описание расширения | Произвольный текст, описывающий наш юзерскрипт |
name | Название расширения | Название скрипта в произвольной форме |
permissions | Разрешения для нашего расширения | Необходимые разрешения безопасности. Первый параметр в примере — маска корссдоменных запросов http://*/*. Она позволяет фоновой странице посылать запросы на любые домены. Второй параметр задаёт нелимитируемый localStorage. |
version | Версия расширения | Версия в формате x.x.x.x |
background.html
Фоновая страница представляет собой обычную html страницу, которая загружается в «невидимый таб» при запуске расширения и работает в фоне в течение всего жизненного цикла расширения.
Ограничения безопасности фоновой страницы настраиваются через параметр permissions в файле-манифесте. Именно через фоновую страницу обходятся ограничения юзерскриптов. Фоновая страница для упакованных юзерскриптов представляет собой proxy, который может «общаться» с юзерскриптом посредством chrome.extension api (Описание).
С теорией покончим, время
Рассмотрим подробнее проксирование кроссдоменных запросов из юзерскрипта.
Код background.html:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
/**
* Кроссдоменные запросы для Хрома.
* XMLHttpRequest на фоновой странице избавлен от CORP (Cross Origin Request Policy),
* т.е. может посылать запросы на другие домены.
* Ниже реализован простой метод GET
*/
function get(url, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function (data) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
callback(data.srcElement.responseText);
} else {
callback(null);
}
}
}
// Note that any URL fetched here must be matched by a permission in
// the manifest.json file!
xhr.open('GET', url, true);
xhr.send();
};
/**
* Обработчик события chrome.extension api.
* Нужен лдя непосредственного проксирования
* @param request Object Данные нашего api-запроса.
* @param sender Object Объект, характеризующий происхождение нашего запроса.
* @param callback Function Коллбэк, который мы передаём параллельно с api-запросом.
* /
function onRequest(request, sender, callback) {
// В данном примере поддерживается только действие xget.
// В целом же можно построить довольно неплохую RPC-cистему
if (request.action == 'xget') {
get(request.url, callback);
}
};
// Регистрируем обработчик события.
chrome.extension.onRequest.addListener(onRequest);
// Из скрипта обращение к прокси будет выглядеть так:
// chrome.extension.sendRequest({'action' : 'xget', 'url':url}, callback);
</scrip>
<body></html>
Код с английскими комментариями доступен на pastebin.com
Вызов из юзерскрипта:
/**
* Этот код располагается в юзерскрипте
* Тестовый вызов: get("http://example.com",alert);
*/
function get(url, callback) {&
chrome.extension.sendRequest({ 'action':'xget', 'url':url}, callback);
}
Этот метод работает в Google Chrome. Кроссдоменные запросы из юзерскриптов в других браузерах мы рассмотрим в одной из следующих статей.
Собираем, тестируем
Для сборки расширения нам понадобится:
- Создать отдельную папку (для удобства)
- Положить в неё manifest.js, background.html и файл юзерскрипта
- Упаковать расширение при помощи Chrome (Натсройки — Расширения — Упаковать расширение. См. скриншот)
Для тестирования мы можем установить распакованное расширение (спасибо theOnlyBoy за наводку). Вместо упаковки (пункт 3) жмём «Установить распакованное расширение».
В итоге наше расширение установится как и обычное упакованное (плюс будет милая и удобная ссылочка Reload для перезагрузки расширения, см. скриншот).
Заключение
На этом на сегодня всё, оставайтесь с нами!
Жду вопросы, критику и обсуждения в комментариях.
Список статей:
- Учимся писать userscript'ы
- Userscripts. Углубляемся
- » Userscripts. Упаковываем юзерскрипт для Chrome
- Usersctripts. Кроссдоменные запросы