Что может быть лучше для того, чтобы научиться создавать расширение для Chrome, чем сделать Интернет более привлекательным с помощью изображений Пикачу?

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

Код этого руководства доступен здесь.

Первое, что вам нужно сделать при создании любого расширения Chrome, - это начать с создания файла manifest.json в корне каталога расширения. На данный момент этот файл будет содержать только следующую базовую информацию о вашем расширении:

Вот что означает все в этом файле:

  1. name: Название расширения. Я назвал расширение «Пикачу везде»
  2. версия: это версия расширения. Когда вы публикуете расширение в Интернет-магазине Chrome и вам нужно его обновить, вам нужно будет увеличить номер версии, поэтому лучше начинать с меньшего номера.
  3. description: (Необязательно) Описание вашего расширения.
  4. manifest_version. Начиная с Chrome 18, разработчики должны использовать версию манифеста 2, поскольку версия манифеста 1 устарела.
  5. значки: (необязательно) Здесь мы указываем значок расширения. Этот значок будет отображаться на панели инструментов вашего браузера, в Интернет-магазине Chrome и в любом другом месте, где требуется его отображение. По этой причине рекомендуется использовать значки разных размеров. Я использовал значок из Free Icons PNG и изменил размер значков с помощью https://resizeimage.net/ (вы можете найти изображения в репозитории GitHub). Пути, указанные для этих изображений, указаны относительно корня расширения.

Благодаря этому у нас есть ядро ​​любого расширения Chrome. Затем мы добавим расширение в браузер.

Перейдите в chrome: // extensions. Там вы можете переключить режим разработчика в правом верхнем углу. После этого появится новая панель инструментов с тремя кнопками: Загрузить распакованный, Упаковать расширение и Обновить. Нажмите Загрузить распакованный и выберите каталог вашего расширения.

Как только вы это сделаете, вы увидите, что ваше новое расширение Chrome теперь работает. Да, ничего не делает, но работает.

В расширениях Chrome вы можете использовать два типа скриптов. Существуют фоновые сценарии и сценарии содержимого. Фоновые скрипты выполняются (очевидно) в фоновом режиме. Они загружаются при необходимости и выгружаются при простое. Они используются для прослушивания определенных событий в вашем расширении Chrome.

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

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

Давайте создадим наш сценарий содержимого в assets/js/contentScript.js и включим следующий сценарий, чтобы проверить, работает ли наше расширение:

Еще нам нужно указать Chrome, какой сценарий нам нужно запустить как сценарий содержимого. Добавьте следующие строки в manifest.json

Здесь мы используем content_scripts в качестве ключа со значением в виде массива. Вот что означает все в массиве:

  1. совпадения: здесь вы можете указать, по каким URL-адресам должен запускаться сценарий содержимого. В нашем случае мы хотим, чтобы наш контентный скрипт запускался на всех страницах. Итак, мы используем заполнитель «‹all_urls›», чтобы указать это.
  2. all_frames: этот ключ используется, чтобы позволить расширению указывать, должны ли файлы JavaScript и CSS вставляться во все фреймы, соответствующие указанным требованиям URL, или только в самый верхний фрейм на вкладке.
  3. js: здесь мы указываем сценарий, который хотим запустить как сценарий содержимого. Вы можете указать более одного скрипта, поэтому значение должно быть массивом

Теперь мы готовы протестировать наш сценарий содержания.

Но прежде чем мы это сделаем, нам нужно сделать один маленький шаг. Чтобы сообщить chrome, что мы обновили наше расширение chrome, нам нужно вернуться к chrome: // extensions, перейти к нашему расширению и нажать значок перезагрузки.

Чтобы проверить, работает ли наш сценарий содержимого, перейдите на любую желаемую веб-страницу, перезагрузите страницу, если она была открыта раньше, затем щелкните правой кнопкой мыши и нажмите «Проверить». В DevTools откройте вкладку Консоль. Как и ожидалось, вы увидите в консоли:

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

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

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

С помощью этого API шаги для достижения того, что нам нужно, будут следующими:

  1. Получить все элементы изображения на веб-странице.
  2. Выполните запрос GET к API, чтобы получить случайную ссылку на изображение Пикачу.
  3. Замените атрибуты src элементов изображения полученными нами ссылками.

Все это звучит хорошо и просто, но есть одна сложность: скрипты контента в расширениях Chrome не могут выполнять запросы Cross-Origin.

Итак, как мы можем получить URL-адреса изображений из API? Нам понадобится фоновый скрипт.

Как мы указали ранее, фоновые скрипты выполняются в фоновом режиме в Chrome. Они не зависят от какой-либо веб-страницы.

Скрипты в расширениях Chrome изолированы друг от друга. Однако у них есть общие средства связи через Chrome API.

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

Сначала это может показаться сложным, но на самом деле это делается очень просто.

Давайте сначала начнем с создания фонового скрипта и посмотрим, как он работает. Создайте assets/js/background.js со следующим содержанием:

Теперь нам нужно сообщить Chrome, что только что созданный файл будет нашим фоновым скриптом. Для этого нам нужно вернуться к нашему manifest.json и добавить следующее:

Вот что все означает:

  1. скрипты: массив, содержащий пути скриптов, которые мы будем использовать в качестве фоновых скриптов. В нашем случае это всего один.
  2. постоянный: всегда должен иметь значение false, если расширение не использует API веб-запросов Chrome для блокировки или изменения сетевых запросов.

Теперь Chrome узнает о нашем фоновом скрипте. Он будет загружать его, когда это необходимо, и выгружать, когда он простаивает.

Чтобы протестировать наш фоновый скрипт, нам нужно перезагрузить наше расширение, как мы это делали ранее.

Как только вы это сделаете, вы увидите новую ссылку, появившуюся в информационном поле вашего расширения с текстом «проверить фоновую страницу просмотров»:

Если вы нажмете на него, откроется новый DevTool и в консоли вы увидите:

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

Вернемся к нашей цели снова. Теперь нам нужно прослушивать сообщения в нашем фоновом скрипте и при получении нового сообщения получить URL-адрес из Pikachu API.

Чтобы прослушивать сообщения, мы будем использовать следующий метод в API Chrome:

Нам нужно передать функцию addListener. Эта функция будет выполняться при получении любого нового сообщения. Функция принимает три параметра:

  1. message: отправленное сообщение любого типа.
  2. отправитель: типа MessageSender
  3. senderResponse: функция обратного вызова для вызова (не более одного раза), когда у вас есть ответ. Эта функция отправляется отправителем при отправке сообщения.

Вот как теперь должен выглядеть наш файл background.js:

Теперь наш фоновый скрипт готов к приему сообщений, но сообщения не отправляются.

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

Чтобы отправлять сообщения, нам нужно будет использовать следующий метод из API Chrome:

Отправляются следующие параметры:

  1. extensionId: (Необязательно) идентификатор расширения, которому мы отправляем сообщение. Если он не указан, сообщение будет отправлено на наш собственный добавочный номер.
  2. message: отправляемое нами сообщение типа any.
  3. варианты: необязательно
  4. responseCallback: функция, вызываемая после получения сообщения. Это параметр senderResponse в предыдущем методе, который мы видели.

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

Вот что мы делаем в приведенном выше коде:

  1. Строка 1: получить все элементы изображения на веб-странице.
  2. Строка 2–6. Просмотрите элементы изображения. Для каждого элемента мы отправляем сообщение фоновому скрипту. Как видите, мы опускаем необязательные параметры extensionId и options. Первый параметр - это сообщение, которое мы отправляем, а второй параметр - это функция обратного вызова, которую мы хотим, чтобы фон выполнялся после получения ссылки на изображение.

Мы отправляем объект {msg: ‘image’, index: i} нашему расширению. У этого объекта есть два свойства. Первый - указать, о чем идет речь. В нашем расширении это может быть не очень полезно, но если у вас есть расширение, которое использует разные типы сообщений, рекомендуется различать, для чего предназначено каждое сообщение. Второе свойство - указать индекс изображения, на которое ссылается ссылка, в массиве images. Причина в том, что функция обратного вызова, заменяющая изображение, будет вызываться асинхронно, поэтому i может указывать на другой индекс во время его выполнения.

Функция обратного вызова получает объект с двумя свойствами. data будет данными, полученными в результате вызова API, а index будет индексом изображения в массиве images. После вызова он установит для изображения индекс в изображениях свойство ссылки данные.

Теперь нам нужно получать данные из API в нашем фоновом сценарии всякий раз, когда сценарий содержимого отправляет сообщение. Мы можем сделать это следующим образом:

Вот что здесь происходит:

  1. Строка 1: Слушайте сообщения в нашем расширении.
  2. Строка 2: проверьте, должно ли сообщение получить URL-адрес изображения. При этом будет использоваться атрибут msg, который мы передали при отправке сообщения в contentScript.
  3. Строка 3–8: Если условие в Строке 2 выполняется, получите данные из API. В первом Promise мы получаем текст ответа, затем во втором Promise мы анализируем объект JSON и вызываем senderResponse, который является функцией обратного вызова, указанной отправителем сообщения. С его помощью мы передаем объект с параметрами data (данные, полученные через вызов API) и index (индекс изображения, отправленный отправителем).
  4. Строка 9: простая обработка любой возможной ошибки.
  5. Строка 10: если отправитель указывает функцию обратного вызова, она должна быть вызвана до того, как прослушиватель прекратит выполнение, иначе он выдаст ошибку. В нашем случае нам нужно дождаться ответа от API, который произойдет асинхронно, поэтому мы возвращаем true, чтобы указать, что он будет вызываться асинхронно.

Хорошо, наши скрипты готовы. Осталось только одно - нам нужно дать разрешение API в нашем manifest.json:

Все, что вам нужно сделать сейчас, это перезагрузить расширение в chrome: // extensions, затем открыть любую страницу и везде видеть Пикачу!

Конечно, это расширение не заменит фоновые изображения. Это можно сделать, перебирая элементы, проверяя, есть ли у них фоновые изображения, и заменяя их таким же образом.