Кросс-браузерное веб-расширение для пользовательских скриптов Ч.2

    В этой статье я продолжаю цикл публикаций, в котором я хочу рассказать о своём опыте написания веб-расширения для браузеров. У меня уже был опыт создания веб-расширения, которое установили около 100 000 пользователей Chrome, которое работало автономно, но в данном цикле статей я решил углубиться в процесс разработки веб-расширения тесно интегрировав его с серверной частью.

    imageimageimageimageimage

    Часть 1, Часть 3, Часть 4

    Выбор фреймворка для серверной части


    В самом начале своей идеи я думал как можно реализовать сохранение данных, полученных в результате работы скрипта. На ум приходила возможность использования locaStorage или подобных решений для базы данных на стороне клиента. По мере продвижения планирования кода по этому пути выяснилось, что загрузка файлов и хранение на компьютере пользователя не самая хорошая идея, так как пользователь будет привязан к одному компьютеру.

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

    Таким образом был выбран путь использования XHR совместно с RESTful API. Этот вариант также позволяет в будущем использовать тот же самый код для построения конвейерной системы поставки данных. Например, получение позиций веб-ресурса в выдаче поисковой системы может быть запланировано в ежедневный цикл. После чего стороннее приложение запрашивает данные полученные в результате работы скрипта по API и строит график, показывающий тенденцию изменения позиции в поисковой выдачи.

    Многие фреймворки на разных языках программирования имеют библиотеки, модули и пакеты для быстрой разработки RESTful серверных приложений. Около 12 лет я работал с разными фреймворками на базе PHP, а последние 3 года я работаю ещё и с Meteor.js. Этот фреймворк работает поверх node.js, поэтому я выбрал его для серверной части из-за высокой производительности (в среднем 112 миллисекунд на запись одной строки данных, полученных от выполнения скрипта) и богатого набора готовых пакетов для построения приложения.

    В качестве RESTful библиотеки я выбрал пакет github.com/kahmali/meteor-restivus, который, в прочем, было необходимо пропатчить, так как он неправильно работал с hook авторизацией и защитой от техники бесконечного подбора паролей.

    Restivus имеет хороший функционал для описания RESTful API и поддерживает работу авторизированным или анонимным способом. В качестве подтверждения полномочий на выполнение определенным пользователем метода по RESTful адресу используется token и userId. Эти параметры можно хранить в localStorage веб-разрешения и использовать при вызове XHR.

    Для административной зоны я выбрал расширяемый и хорошо конфигурируемый пакет github.com/yogiben/meteor-admin, который позволил мне сократить время на создание многих однотипных страниц для нужд команды безопасности.

    Проектирование интерфейса для веб-расширения


    Интерфейс играет решающую роль в выборе пользователем того или иного продукта. Удобство и минимализм были выбраны главными критериями интерфейса веб-расширения. В дальнейшем была добавлено эстетическая сторона для придания законченности всему приложению.

    В качестве css/html фреймворка был выбран semantic-ui. При этом я отказался от дополнительных пакетов npm и сборочных механизмов типа webpack для минимизации зависимостей и размера веб-расширения. Код написан максимально прозрачно, с использованием только трёх js библиотек и сторонних файлов.

    Для начала процесса был составлен список необходимых страниц. В этот список были сгруппированы страницы для работы с пользовательской учетной записью.

    1. Страница входа
    2. Страница регистрации
    3. Страница сброса пароля

    На данном этапе возникла проблема одноразовой ссылки для сброса пароля. В обычном приложении пользователь может пройти по ссылке, сбросить пароль, а далее войти в приложение. Веб-расширение может “перехватывать” ссылки при помощи navigator.registerProtocolHandler и авторизовать пользователя в веб-расширении, но не все браузеры это поддерживают. Поэтому было решено сбрасывать пароль по ссылке, а далее пользователь может входить в веб-расширение при помощи нового пароля.

    Ниже изображена форма для регистрации нового пользователя в веб-расширении.


    Здесь видны элементы для социального маркетинга, такие как Invite code и ссылки для распространения в социальных сетях рядом с элементом отправки вопроса в службу поддержки.

    После регистрации, либо после авторизации пользователь может редактировать свой профиль прямо в веб-расширении. Это качественно улучшает текущее решение, потому что убирает необходимость работать с отдельным веб-сайтом. Пользователь может выполнять все действия в одном месте.


    Все экраны разделены на вкладки, что позволяет быстро перемещаться между экранами и играет роль своеобразного меню. В некоторых случаях для более наглядного представления сознательно отказано в минимизации элементов для текущей итерации. Например подписи кнопок вынесены на сами кнопки, хотя в будущем планируется замена вертикального списка кнопок на горизонтальный и вынос подписей в тултипы. Сделано это для максимальной простоты презентации веб-расширения для новых пользователей. Так сделан главный экран со списком скриптов для текущей итерации.


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


    Далее пользователь может выставить признак публичности скрипта, что даст возможность другим пользователям использовать опыт сообщества веб-расширения.

    Публичные скрипты обладают рядом ограничений. Например они не могут быть использованы для автозагрузки на страницу, в планировщике задач и иметь горячие клавиши. При этом каждый публичный скрипт имеет возможность “редактирования”, во время которого пользователь может убрать признак публичности и сохранить его в приватном состоянии как собственный скрипт. Эти дополнительные действия необходимы для защиты от недобросовестных разработчиков. При “редактировании” публичного скрипта, пользователь будет обязан просмотреть код и принять решение о его использовании для своих нужд.

    Загрузка файлов в веб-расширении реализована при помощи чтения содержимого файла в буфер, кодирования и дальнейшей отправки по XHR каналу на сервер. На сервере POST запрос обрабатывается и файла отправляется в облачное хранилище. В скриптах пользователи могут читать загруженные файлы через GC.loadFile(‘filename.ext’);, функцию из внутренней библиотеки, о которой будет написана отдельная статья.


    Каждый скрипт может записывать данные от вычислений при помощи вызова функции внутренней библиотеки. Каждый вызов будет записывать одну строку в ячейку с одинаковым именем для всех строк. Таким образом можно записывать csv файлы. На экране ниже представлен интерфейс для работы с выходными данными. Пользователь может скачать данные прямо из веб-расширения, отправить сгенерированный файл себе на емайл, получить ссылку на API для использования в стороннем приложении, либо удалить данные.


    Все действия изменяющие состояние скрипта, как например действие удаления, требуют подтверждения. В веб-расширении есть ограничение на использование pop-up или confirm окон, так как оно само имеет интерфейс запущенный в pop-up. Поэтому используется механизм ввода подтверждающего слова.


    В следующей статье я расскажу о «подводных камнях при реализации взаимодействия веб-расширения и серверной частью».
    Поделиться публикацией

    Комментарии 1

      0
      Извините, но «REST full» режет глаза. Правильно — «RESTful».

      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

      Самое читаемое