Простое введение в разработку расширений для Chrome почти на 10 000 символов.

внешний интерфейс

предисловие

Эта статья предназначена для того, чтобы начать разработку для Chrome. Если вам нужна более глубокая разработка, вы можете перейти наchromeИсследование на официальном сайте. Официальный предоставил демонстрацию для изменения цвета фона веб-страницы, вы можетенажмите, чтобы скачать, если у вас возникли проблемы с загрузкой, вы можете перейти кgithub

В этой статье будут перечислены некоторые часто используемые описания концепций, включая сравнение 5 типов js, 6 ядер, обмен сообщениями и некоторые динамические инъекции, выпуск пакетов и т. д.

В этой статье будет последняя демонстрация Chrome, которая меняет страницу на Diablo.

Демо-демонстрационный эффект выглядит следующим образом:

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

Что такое плагин для хрома?

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

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

Extensions are small software programs that customize the browsing experience. They enable users to tailor Chrome functionality and behavior to individual needs or preferences. They are built on web technologies such as HTML, JavaScript, and CSS.

Chrome Extensionэто небольшая программа, которая может настроить работу в Интернете. Они позволяют пользователям настраивать функции и поведение Chrome в соответствии с личными потребностями или предпочтениями. Он построен на веб-технологиях, таких как HTML, JavaScript и CSS.

Зачем изучать разработку расширений Chrome?

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

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

6 ядер

6 основных концепций включаютManifest Format,Manage Events,Design User Interface,Content Scripts,Declare Permissions and Warn Users,Give Users Options

Manifest Format - официальная документация

каждыйChrome ExtensionОба имеют файл манифеста в формате JSON с именемmanifest.json, предоставление важной информации. Используется для настройки всей конфигурации, связанной с плагином, должен быть размещен в корневом каталоге проекта. Простая конфигурация выглядит так

{
  "name": "TimeStone",
  "manifest_version": 2,
  "version": "1.0",
  "description": "TimeStone 扩展程序",
  "page_action": {
    "default_icon": "images/icon.png",
    "default_title": "TimeStone 插件",
    "default_popup": "html/home.html"
  },
  "background": {
    "scripts": ["js/background.js"]
  },
  "options_page": "html/options.html",
  "homepage_url": "https://juejin.cn/user/4230576473387773",
  "permissions": [
    "tabs",
    "storage",
    "activeTab"
  ]
}

Конфигурация описывается следующим образом: [Примечание] Логотип должен быть жирным, рекомендуется использовать выделение

  • manifest_version- Должен быть, и только 2
  • name- название плагина
  • version- номер версии
  • description- описывать
  • icons- Значок
  • homepage_url- Домашняя страница плагина, ха-ха, обычно я устанавливаю ее как домашнюю страницу Nuggets.
  • background- Есть два способа указать фоновый JS или фоновую страницу, которая всегда будет находиться
    "background":
     {
     	// 2种指定方式,如果指定JS,那么会自动生成一个背景页
     	"page": "background.html"
     	//"scripts": ["js/background.js"]
     }
    
  • browser_actaction, page_action, приложение- Отображается в правом верхнем углу браузера, можно выбрать только один из трех
    "browser_action": 
     {
     	"default_icon": "img/icon.png",
     	// 图标悬停时的标题,可选
     	"default_title": "这是一个示例Chrome插件",
     	"default_popup": "popup.html"
     }
     "page_action":
     {
     	"default_icon": "img/icon.png",
     	"default_title": "我是pageAction",
     	"default_popup": "popup.html"
     }
    
  • permissions- Настройки приложения разрешения плагина
    "permissions":
     [
     	"contextMenus", // 右键菜单
     	"tabs", // 标签
     	"notifications", // 通知
     	"webRequest", // web请求
     	"webRequestBlocking",
     	"storage", // 插件本地存储
     ]
    
  • web_accessible_resources- Список подключаемых ресурсов, к которым могут напрямую обращаться обычные страницы, если они не заданы, к ним нельзя получить прямой доступ
  • chrome_url_overrides- Переопределить страницу браузера по умолчанию
  • options_ui- Написание страницы конфигурации плагина
  • omnibox- Зарегистрируйте ключевое слово в адресную панель, чтобы обеспечить предложения поиска, можно установить только одно ключевое слово
    "omnibox": { "keyword" : "rick" }
    
  • default_locale- язык по умолчанию
  • devtools_page- запись страницы devtools, обратите внимание, что она может указывать только на файл HTML, а не на файл JS.

Управление событиями с помощью фоновых сценариев -официальная документация

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

Фоновые страницы загружаются по мере необходимости и выгружаются при бездействии. Вот некоторые примеры событий:

  • Расширение сначала устанавливается или обновляется до новой версии.
  • Фоновая страница прослушивает событие, и оно было отправлено.
  • Скрипты содержимого или другие расширенияотправлять сообщения.
  • Вызывается другим представлением в программе (например, всплывающим окном)runtime.getBackgroundPage.

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

Фоновые сценарии регистрации (Register Background Scripts)

существуетmanifest.jsonнастройте его следующим образом

{
  "name": "Awesome Test Extension",
  ...
  "background": {
    "scripts": ["js/background.js"],
    "persistent": false
  },
  ...
}

Инициализировать расширение

мониторruntime.onInstalledсобытие, используйте это событие, чтобы установить состояние или выполнить инициализацию.Напримерконтекстное меню.

 chrome.runtime.onInstalled.addListener(function() {
    chrome.contextMenus.create({
      "id": "sampleContextMenu",
      "title": "Sample Context Menu",
      "contexts": ["selection"]
    });
  });

установить слушателя

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

Слушатели должны быть зарегистрированы синхронно с начала страницы.

 chrome.runtime.onInstalled.addListener(function() {
    chrome.contextMenus.create({
      "id": "sampleContextMenu",
      "title": "Sample Context Menu",
      "contexts": ["selection"]
    });
  });

  // This will run when a bookmark is created.
  chrome.bookmarks.onCreated.addListener(function() {
    // do something
  });

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

 chrome.runtime.onInstalled.addListener(function() {
    // ERROR! Events must be registered synchronously from the start of
    // the page.
    chrome.bookmarks.onCreated.addListener(function() {
      // do something
    });
  });

Расширения могут удалять прослушиватели из своих фоновых сценариев, вызывая метод removeListener. Если все прослушиватели для события удалены, Chrome больше не будет загружать фоновый скрипт расширения для этого события.

  chrome.runtime.onMessage.addListener(function(message, sender, reply) {
      chrome.runtime.onMessage.removeListener(event);
  });

фильтровать события

Воспользуйтесь поддержкойФильтр событийAPI ограничивает слушателей случаями, в которых расширение заботится. Если расширение слушаетtabs.onUpdatedсобытие, попробуйте использоватьwebNavigation.onCompletedСобытия с фильтрами, так как API вкладок не поддерживает фильтры.

chrome.webNavigation.onCompleted.addListener(function() {
      alert("This is my favorite website!");
  }, {url: [{urlMatches : 'https://www.google.com/'}]});

реагировать на события

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

  chrome.runtime.onMessage.addListener(function(message, callback) {
    if (message.data == “setAlarm”) {
      chrome.alarms.create({delayInMinutes: 5})
    } else if (message.data == “runLogic”) {
      chrome.tabs.executeScript({file: 'logic.js'});
    } else if (message.data == “changeColor”) {
      chrome.tabs.executeScript(
          {code: 'document.body.style.backgroundColor="orange"'});
    };
  });

Удалить фоновые скрипты

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

 chrome.storage.local.set({variable: variableInformation});

Если расширение используетобмен сообщениями, убедитесь, что все порты закрыты. Фоновые скрипты не выгружаются, пока не будут закрыты все порты сообщений. Слушатьruntime.Port.onDisconnectСобытия предоставят информацию о том, когда открытые порты закрыты. использоватьruntime.Port.disconnectЗакройте их вручную.

 chrome.runtime.onMessage.addListener(function(message, callback) {
    if (message == 'hello') {
      sendResponse({greeting: 'welcome!'})
    } else if (message == 'goodbye') {
      chrome.runtime.Port.disconnect();
    }
  });

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

Вы можете открыть диспетчер задач, щелкнув меню Chrome, наведя указатель мыши на «Дополнительные инструменты» и выбрав «Диспетчер задач».

Фоновый скрипт выгружается через несколько секунд бездействия. Если вам нужна уборка в последнюю минуту, настройтесьruntime.onSuspendмероприятие.

  chrome.runtime.onSuspend.addListener(function() {
    console.log("Unloading.");
    chrome.browserAction.setBadgeText({text: ""});
  });

Однако предпочтение следует отдавать постоянным данным, а не runtime.onSuspend. Это не позволяет столько очистки и не помогает, когда происходит сбой.

Design User Interface - официальная документация

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

Активировать расширение на всех страницах

Когда функциональность расширения доступна в большинстве случаев, используйтеbrowser_action.

  • существуетmanifest.jsonрегистрbrowser_action

      {
      "name": "My Awesome browser_action Extension",
      ...
      "browser_action": {
        ...
      }
      ...
    }
    

    При объявлении «browser_action» значок остается цветным, указывая на то, что расширение доступно для пользователя.

  • Add a badge

    Так называемый значок предназначен для отображения текста на значке и отображения красочного баннера над значком браузера, содержащего до четырех символов. Они могут использоваться только расширениями, объявленными «browser_action» в их манифесте.

    Установите текст значка по телефону , а цвет баннера по телефону .chrome.browserAction.setBadgeText chrome.browserAction.setBadgeBackgroundColor

Активировать расширение на выбранной странице

Когда функциональность расширения доступна только в определенных случаях, используйтеpage_action.

  • существуетmanifest.jsonрегистрpage_action
      {
      "name": "My Awesome page_action Extension",
      ...
      "page_action": {
        ...
      }
      ...
    }
    
    Объявление «page_action» будет окрашивать значок только в том случае, если расширение доступно пользователю, в противном случае оно будет отображаться в оттенках серого.

  • Определить правила для активации расширений
    вфоновый скриптсерединаchrome.declarativeContentизruntime.onInstalledВызывается под прослушивателем, чтобы определить, когда можно использовать расширенные правила.через URLнепрерывныйДействия страницыПример расширения устанавливает условие, согласно которому URL-адрес должен содержать «g». Если условия соблюдены, добавочный номер звонит.declarativeContent.ShowPageAction() [Примечание]: Вот ответ вjd.comКогда вы находитесь на странице вкладки, плагин будет выделен, а цвет на других вкладках будет серым.

      chrome.runtime.onInstalled.addListener(function() {
      // Replace all rules ...
      chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
        // With a new rule ...
        chrome.declarativeContent.onPageChanged.addRules([
          {
            // That fires when a page's URL contains a 'g' ...
            conditions: [
              new chrome.declarativeContent.PageStateMatcher({
                pageUrl: { urlContains: 'jd.com' },
              })
            ],
            // And shows the extension's page action.
            actions: [ new chrome.declarativeContent.ShowPageAction() ]
          }
        ]);
      });
    });
    
  • Включить или отключить расширения Расширения, использующие «page_action», могут сделать это, вызвавpageAction.showи активировать и деактивировать динамическиpageAction.hide.

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

    chrome.runtime.onMessage.addListener(function(req, sender) {
      chrome.storage.local.set({'address': req.address})
      chrome.pageAction.show(sender.tab.id);
      chrome.pageAction.setTitle({tabId: sender.tab.id, title: req.address});
    });
    

Предоставить значок расширения

Для представления расширения требуется хотя бы один значок. Хотя допустим любой формат, поддерживаемый WebKit, включая BMP, GIF, ICO и JPEG, значки в формате PNG обеспечивают наилучшие визуальные эффекты.

  • Укажите значки панели инструментов

    Специальные значки панели инструментов зарегистрированы вmanifest.jsonПод "значком по умолчанию"browser_actionилиpage_actionв полях манифеста. Рекомендуется включать несколько размеров, чтобы соответствовать 16 местам наклона. Рекомендуются размеры не менее 16 x 16 и 32 x 32.

     {
      "name": "My Awesome page_action Extension",
      ...
      "page_action": {
        "default_icon": {
          "16": "extension_toolbar_icon16.png",
          "32": "extension_toolbar_icon32.png"
        }
      }
      ...
    }
    

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

  • Создание и регистрация дополнительных значков. Используйте дополнительные значки следующих размеров за пределами панели инструментов.

    Размер значка Использование значков
    16x16 фавикон на странице расширения
    32x32 Компьютеры Windows обычно требуют этого размера. Предоставление этой опции предотвратит искажение размера по сравнению с опцией 48x48.
    48x48 Отображается на странице управления расширениями
    128x128 Отображается при установке и в интернет-магазине Chrome
    {
        "name": "My Awesome Extension",
        ...
        "icons": {
          "16": "extension_icon16.png",
          "32": "extension_icon32.png",
          "48": "extension_icon48.png",
          "128": "extension_icon128.png"
        }
        ...
    }
    

Другие функции пользовательского интерфейса

  • Popup

    Всплывающее окно — это HTML-файл, который отображается в специальном окне, когда пользователь щелкает значок на панели инструментов. Всплывающее окно работает так же, как и веб-страница: оно может содержать ссылки на таблицы стилей и теги сценариев, но не позволяет использовать встроенный JavaScript.

    Drink Water EventПример всплывающего окна, показывающего доступные параметры таймера. Пользователь устанавливает оповещение, нажимая одну из предоставленных кнопок.

<html>
    <head>
      <title>Water Popup</title>
    </head>
    <body>
        <img src='./stay_hydrated.png' id='hydrateImage'>
        <button id='sampleSecond' value='0.1'>Sample Second</button>
        <button id='15min' value='15'>15 Minutes</button>
        <button id='30min' value='30'>30 Minutes</button>
        <button id='cancelAlarm'>Cancel Alarm</button>
     <script src="popup.js"></script>
    </body>
  </html>

Вышеупомянутые настройки можно использовать в browser_action или page_action.

{
    "name": "Drink Water Event",
    ...
    "browser_action": {
      "default_popup": "popup.html"
    }
    ...
  }

Всплывающие окна также можно устанавливать динамически, вызывая или .browserAction.setPopup,pageAction.setPopup

chrome.storage.local.get('signed_in', function(data) {
    if (data.signed_in) {
      chrome.browserAction.setPopup({popup: 'popup.html'});
    } else {
      chrome.browserAction.setPopup({popup: 'popup_sign_in.html'});
    }
  });
  • Подсказка — используйте всплывающую подсказку, чтобы предоставить пользователю краткое описание или инструкции при наведении курсора на значок браузера.

Подсказка уже в поле default_titlebrowser_actionилиpage_actionзарегистрирован в.

  {
  "name": "Tab Flipper",
   ...
    "browser_action": {
      "default_title": "Press Ctrl(Win)/Command(Mac)+Shift+Right/Left to flip tabs"
    }
  ...
 }

Содержимое всплывающих подсказок также можно обновить с помощью методовbrowserAction.setTitle and pageAction.setTitle.

 chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.browserAction.setTitle({tabId: tab.id, title: "You are on tab:" + tab.id});
  });
  • Омнибокс Пользователи могут проходитьОмнибоксВызов функции расширения. Включите в манифест поле «омнибокс» и укажите ключевое слово. существуетадресная строка новая вкладка поискПример расширения использует "NT" в качестве ключевого слова.
 {
    "name": "Omnibox New Tab Search",\
    ...
    "omnibox": { "keyword" : "nt" },
    "default_icon": {
      "16": "newtab_search16.png",
      "32": "newtab_search32.png"
    }
    ...
  }

Когда пользователь вводит «nt» в омнибокс, он активирует расширение. Чтобы сигнализировать пользователю, он окрашивает предоставленный значок 16x16 в оттенки серого и включает его в омнибокс рядом с расширением.

Расширение прослушивает события. При срабатывании расширения откроется новая вкладка с поиском Google для записи пользователя.omnibox.onInputEntered

chrome.omnibox.onInputEntered.addListener(function(text) {
  // Encode user input for special characters , / ? : @ & = + $ #
  var newURL = 'https://www.google.com/search?q=' + encodeURIComponent(text);
  chrome.tabs.create({ url: newURL });
});

  • Контекстное меню - контекстное меню

    Меню правой кнопки мыши должно применятьсяcontextMenusразрешения,

      {
      "name": "Global Google Search",
      ...
      "permissions": ["contextMenus", "storage"],
      "icons": {
        "16": "globalGoogle16.png",
        "48": "globalGoogle48.png",
        "128": "globalGoogle128.png"
     }
     ...
    }
    

    Рядом с новым пунктом меню появляется значок размером 16x16.

Создайте контекстное меню, вызвавcontextMenus.createизbackground script. Это должно быть вruntime.onInstalledЗавершено под событием прослушивателя.

const kLocales = {
    'com.au': 'Australia',
    'com.br': 'Brazil',
    'ca': 'Canada',
    'cn': 'China',
    'fr': 'France',
    'it': 'Italy',
    'co.in': 'India',
    'co.jp': 'Japan',
    'com.ms': 'Mexico',
    'ru': 'Russia',
    'co.za': 'South Africa',
    'co.uk': 'United Kingdom'
  };
 chrome.runtime.onInstalled.addListener(function() {
    for (let key of Object.keys(kLocales)) {
      chrome.contextMenus.create({
        id: key,
        title: kLocales[key],
        type: 'normal',
        contexts: ['selection'],
      });
    }
  });
  • Команды Расширения могут определять конкретныеcommandsи привязать его к комбинации клавиш. Команды, необходимые для регистрации в командах
{
    "name": "Tab Flipper",
    ...
    "commands": {
      "flip-tabs-forward": {
        "suggested_key": {
          "default": "Ctrl+Shift+Right",
          "mac": "Command+Shift+Right"
        },
        "description": "Flip tabs forward"
      },
      "flip-tabs-backwards": {
        "suggested_key": {
          "default": "Ctrl+Shift+Left",
          "mac": "Command+Shift+Left"
        },
        "description": "Flip tabs backwards"
      }
    }
    ...
  }

Команды могут быть использованы для предоставления новых или альтернативных ярлыков браузера.Tab FlipperОбразец расширения монитораcommands.onCommandмероприятиеbackground scriptКомбинируйте и определяйте функции для каждой зарегистрированной комбинации.

  chrome.commands.onCommand.addListener(function(command) {
    chrome.tabs.query({currentWindow: true}, function(tabs) {
      // Sort tabs according to their index in the window.
      tabs.sort((a, b) => { return a.index < b.index; });
      let activeIndex = tabs.findIndex((tab) => { return tab.active; });
      let lastTab = tabs.length - 1;
      let newIndex = -1;
      if (command === 'flip-tabs-forward')
        newIndex = activeIndex === 0 ? lastTab : activeIndex - 1;
      else  // 'flip-tabs-backwards'
        newIndex = activeIndex === lastTab ? 0 : activeIndex + 1;
      chrome.tabs.update(tabs[newIndex].id, {active: true, highlighted: true});
    });
  });
  • Переопределить страницы Расширения могут переопределять HTML-код браузера собственными新建选项卡или书签страница. Он может содержать специализированную логику и стили, но не поддерживает встроенный JavaScript. Одно расширение ограничено охватом одной из трех возможных страниц.

Регистрация выглядит следующим образом

 {
   "name": "Awesome Override Extension",
   ...

   "chrome_url_overrides" : {
     "newtab": "override_page.html",
     "bookmarks": "book.html"
   },
   ...
 }
<html>
  <head>
   <title>New Tab</title>
  </head>
  <body>
     <h1>Hello World</h1>
   <script src="logic.js"></script>
  </body>
 </html>

Content Scripts - официальная документация

Скрипты контента — это файлы, которые запускаются в контексте веб-страницы. с помощью стандартаОбъектная модель документа (DOM), они могут читать информацию о веб-страницах, посещенных браузером, вносить в них изменения и передавать информацию своему родительскому расширению.

Особенности скрипта контента

Скриптами контента можно обмениваться с расширениемИнформациядля доступа к Chrome API, используемому его родительским расширением. Они также могут использовать URL-адрес для доступа к файлу расширения,chrome.runtime.getURL()и используйте тот же результат, что и другие URL-адреса.

  //Code for displaying <extensionDir>/images/myimage.png:
  var imgURL = chrome.runtime.getURL("images/myimage.png");
  document.getElementById("someImage").src = imgURL;

Скрипты содержимого также могут получать доступ к следующим API.

Способ работы

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

Расширения могут работать на веб-страницах с кодом, подобным следующему примеру.

  <html>
    <button id="mybutton">click me</button>
    <script>
      var greeting = "hello, ";
      var button = document.getElementById("mybutton");
      button.person_name = "Bob";
      button.addEventListener("click", function() {
        alert(greeting + button.person_name + ".");
      }, false);
    </script>
  </html>

Расширение может внедрять следующие сценарии контента.

 var greeting = "hola, ";
  var button = document.getElementById("mybutton");
  button.person_name = "Roberto";
  button.addEventListener("click", function() {
    alert(greeting + button.person_name + ".");
  }, false);

Если кнопка нажата, одновременно появятся два будильника.

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

ссылка на обучающее видео

Inject Scripts - Внедрить скрипты

Контент-скрипты могут бытьпрограммноилиМетод объявленияинъекция.

  • Программно внедрить

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

     {
      "name": "My extension",
      ...
      "permissions": [
        "activeTab"
      ],
      ...
    }
    
    

    Скрипты контента могут быть внедрены как код.

      chrome.runtime.onMessage.addListener(
      function(message, callback) {
        if (message == “changeColor”){
          chrome.tabs.executeScript({
            code: 'document.body.style.backgroundColor="orange"'
          });
        }
     });
    

Вы также можете указать файл

 chrome.runtime.onMessage.addListener(
   function(message, callback) {
     if (message == “runContentScript”){
       chrome.tabs.executeScript({
         file: 'contentScript.js'
       });
     }
  });
  • Декларативная инъекция Используйте декларативное внедрение для сценариев контента, которые автоматически запускаются на указанных страницах. Декларативно внедренный скрипт находится здесь"content_scripts"Зарегистрируйтесь в манифесте под полем. Они могут включать файлы JavaScript и/или файлы CSS. Все скрипты содержимого автозапуска должны указыватьобразец соответствия
{
 "name": "My extension",
 ...
 "content_scripts": [
   {
     "matches": ["http://*.nytimes.com/*"],
     "css": ["myStyles.css"],
     "js": ["contentScript.js"]
   }
 ],
 ...
}

имя Типы описывать
matches array of strings нужно. Указывает, на какие страницы будет внедрен этот сценарий содержимого. Дополнительные сведения о синтаксисе этих строк см. в разделе "образец соответствия", информацию о том, как исключить URL-адреса, см. в разделе "Соответствие шаблонам и глобальным переменным".
css array of strings необязательный. Список файлов CSS для вставки на соответствующие страницы. Они будут внедрены в том порядке, в котором они появляются в этом массиве, до того, как будет создана или отображена какая-либо модель DOM для страницы.
js array of strings необязательный. Список файлов JavaScript для вставки на соответствующие страницы. Они вводятся в том порядке, в котором они появляются в этом массиве.
match_about_blank boolean необязательный. Следует ли внедрять скрипт в родительский фрейм about:blank или в фрейм, открытый фрейм которого соответствует одному из шаблонов, объявленных в match. По умолчанию ложно.
exclude_matches array of strings необязательный. Исключите страницы, на которые будет внедрен этот контент-скрипт. Дополнительные сведения о синтаксисе этих строк см.образец соответствия.
include_globs array of strings необязательный. Затем примените совпадения, включая только те URL-адреса, которые также соответствуют этому шаблону. Разработан для имитации ключевых слов Greasemonkey.@include
exclude_globs array of strings необязательный. Применить после, соответствует, чтобы исключить URL-адреса, соответствующие этому глобальному параметру. Разработан для имитации ключевых слов Greasemonkey.@exclude
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}

Вы также можете указать время выполнения, указать структуру и связаться со встроенной страницей.Для дополнительной настройки, пожалуйста, прочитайте официальную ссылкуdeveloper.chrome.com/extensions/…

Declare Permissions and Warn Users (объявить разрешения и предупредить пользователей)

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

Организация разрешений

Разрешения — это известные строки, которые относятся к Chrome API илиобразец соответствиядля предоставления доступа к одному или нескольким хостам. Они перечислены в манифесте и обозначены как требуемые разрешения илиДополнительные разрешения.

 {
    "name": "Permissions Extension",
    ...
    // 必须权限
    "permissions": [
      "activeTab",
      "contextMenus",
      "storage"
    ],
    // 可选权限
    "optional_permissions": [
      "topSites",
      "http://www.developer.chrome.com/*"
    ],
        ...
    "manifest_version": 2
  }

Определите необходимые разрешения -официальный адрес

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

Определите основные функции расширения и необходимые разрешения. Если функция требует разрешения предупреждения, рассмотрите возможность сделать его необязательным.

Запуск дополнительных разрешений с помощью событий

существуетНеобязательное расширение образца разрешенияОсновная функция — перегрузить страницу новой вкладки. Одной из функций является отображение целей пользователя на день. Эта функция требует толькоместо храненияЛицензия, которая не содержит предупреждений.

Расширение имеет дополнительный функционал. Отображает популярные сайты пользователя. Эта функция требуетtopSitesразрешения с предупреждением.

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

Give Users Options - официальная документация

Это страница пользовательских параметров, которая является страницей настроек плагина.Есть две записи, одна из которых — значок, вызываемый правой кнопкой мыши, с меню «Параметры», а другая — на странице управления плагином:

Простая конфигурация

  • полный вариант страницы
{
 "name": "My extension",
 ...
 "options_page": "options.html",
 ...
}
  • Встроенные опции
{
  "name": "My extension",
  ...
  "options_ui": {
    "page": "options.html",
    "open_in_tab": false
  },
  ...
}

Сравнение 5 типов js -Ссылка на ссылку

Расширения JS для Chrome можно в основном разделить на следующие 5 категорий:injected script,content-script,popup js,background jsа такжеdevtools js

Сравнение разрешений

JS-тип доступный API доступ к DOM JS-доступ прямой перекрестный домен
injected script Он ничем не отличается от обычного JS и не имеет доступа ни к какому расширению API. может получить доступ может получить доступ Не можем
content script Доступ возможен только к некоторым API, таким как расширение и среда выполнения. может получить доступ Не можем Не можем
popup js Доступ к большинству API, кроме серии devtools не доступен напрямую Не можем Могу
background js Доступ к большинству API, кроме серии devtools не доступен напрямую Не можем Могу
devtools js Может получить доступ только к некоторым API, таким как инструменты разработки, расширения, среда выполнения и т. д. Могу Могу Не можем

Обмен сообщениями -официальная документация

демонстрационный адрес

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

Связь между расширением и сценариями его содержимого осуществляется с помощью передачи сообщений. Любая сторона может прослушивать сообщения, отправленные с другой стороны, и отвечать на том же канале. Сообщение может содержать любой допустимый объект JSON (пустой, логический, числовой, строковый, массив или объект).

Простой одноразовый пропуск

Если вам нужно только отправить сообщение в другую часть расширения (и при желании вернуть ответ), вы должны использовать упрощенныйruntime.sendMessageилиtabs.sendMessage. Таким образом, вы можете один раз отправить сериализуемое сообщение JSON из сценария содержимого в расширение и наоборот. Необязательный параметр обратного вызова позволяет вам обрабатывать ответ (если есть) с другой стороны.

chrome.runtime.sendMessage({greeting: "hello"}, function(response) {
  console.log(response.farewell);
});

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

chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
  chrome.tabs.sendMessage(tabs[0].id, {greeting: "hello"}, function(response) {
    console.log(response.farewell);
  });
});

На принимающей стороне необходимо установитьruntime.onMessageСлушатели событий для обработки сообщений. Внешний вид такой же, как у сценария контента или страницы расширения.

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
    console.log(sender.tab ?
                "from a content script:" + sender.tab.url :
                "from the extension");
    if (request.greeting == "hello")
      sendResponse({farewell: "goodbye"});
  });

Откройте фоновую страницу по умолчанию, чтобы увидеть сообщение

Content-script.js также ответит

Длинное соединение

Иногда это полезно, когда беседа длится дольше, чем один запрос и ответ. В этом случае вы можете использоватьruntime.connectилиtabs.connectоткрывать долгоживущие каналы от скриптов контента до страниц расширения и наоборот. Каналы могут иметь имя, чтобы можно было различать разные типы соединений.

Когда соединение установлено, оба конца снабженыruntime.PortОбъект, используемый для отправки и получения сообщений через это соединение.

content-scriptСценарий содержимого открывает канал для отправки и получения следующим образом: Отправка запроса к контентному скрипту из расширения выглядит очень похоже, за исключением того, что вам нужно указать вкладку, к которой нужно подключиться. Просто замените соединение подключения в приведенном выше примере наtabs.connectВот и все.

页面与 content-script 建立连接方法如下

var port = chrome.runtime.connect({name: "knockknock"});
port.postMessage({joke: "Knock knock"});
port.onMessage.addListener(function(msg) {
  if (msg.question == "Who's there?")
    port.postMessage({answer: "Madame"});
  else if (msg.question == "Madame who?")
    port.postMessage({answer: "Madame... Bovary"});
});

Для обработки входящих подключений необходимо установитьruntime.onConnectпрослушиватель событий. Это выглядит так же, как в сценарии контента или на странице расширения. Это событие запускается, когда другая часть расширения вызывает «connect()» вместе сruntime.Portобъект. Вот как выглядит ответ на входящие соединения:content-script.js

//监听长连接
chrome.runtime.onConnect.addListener(function(port) {
  console.assert(port.name == "knockknock");
  port.onMessage.addListener(function(msg) {
    if (msg.joke == "Knock knock")
      port.postMessage({question: "Who's there?"});
    else if (msg.answer == "Madame")
      port.postMessage({question: "Madame who?"});
    else if (msg.answer == "Madame... Bovary")
      port.postMessage({question: "I don't get it."});
  });
});

Результаты, как показано ниже:

Портовая жизнь

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

передачаtabs.connect,runtime.connectилиruntime.connectNative, создастPort. Этот порт сразу доступен дляpostMessageОтправьте сообщение на другой конец.

Вызывается, если во вкладке несколько фреймовtabs.connectприведет кruntime.onConnectМножественные вызовы события (один раз на кадр во вкладке). Аналогично, если использоватьruntime.connect, событие onConnect может запускаться несколько раз (один раз на кадр во время расширения).

Возможно, вы захотите узнать, когда соединение закрыто, например, поддерживаете ли вы отдельное состояние для каждого открытого порта. Для этого вы можете прослушатьruntime.Port.onDisconnectмероприятие. Это событие запускается, когда на другой стороне канала нет допустимых портов. Это происходит, когда:

  • Другой конец не используется дляruntime.onConnectслушатель.
  • Вкладка, содержащая порт, выгружается (например, при переходе по вкладке).
  • connectРамки в расположении вызовов разгружены.
  • получить порт (черезruntime.onConnect) выгружаются.
  • позвони на другом концеruntime.Port.disconnect. Обратите внимание, что еслиconnectВызов приводит к нескольким портам на стороне получателя, иdisconnect()вызывается на любой из этих портов, тоonDisconnectСобытия срабатывают только на порту отправителя без запуска на другие порты.

Идентификация общего метода

Динамически внедрять код css

// 动态执行CSS代码,TODO,这里有待验证
chrome.tabs.insertCSS(tabId, {code: 'xxx'});
// 动态执行CSS文件
chrome.tabs.insertCSS(tabId, {file: 'some-style.css'});

Уведомление] Поскольку CSS, введенный через content_scripts, имеет очень высокий приоритет, он уступает только стилю браузера по умолчанию.Если вы не будете осторожны, это может повлиять на эффект отображения некоторых веб-сайтов, поэтому старайтесь не писать некоторые стили, которые повлиять на весь мир. Поэтому обязательно проверяйте его при инъекциях.

динамическое исполнение

официальная документация

// 动态执行JS代码
chrome.tabs.executeScript(tabId, {code: 'document.body.style.filter = "grayscale(1)"'});
// 动态执行JS文件
chrome.tabs.executeScript(tabId, {file: 'script.js'});

[Примечание] Такие страницы, как background и page_action, не могут напрямую обращаться к DOM страницы.chrome.tabs.executeScript({ code: script, })выполнить js

Получить текущий идентификатор окна -Документация

chrome.windows.getCurrent(function(currentWindow)
{
	console.log('当前窗口ID:' + currentWindow.id);
});

Расширение отладки

Отладочная программа, вы можете увидетьРасширение отладкиОфициальный сайт объясняет, в частности, детали, а такжеСсылка на видео

Упаковка и издательство

Мы можем щелкнуть, чтобы упаковать расширение, а затем создать файл .rtx.Если вы хотите опубликовать его в магазине приложений Google, вам необходимо сначала войти в свою учетную запись Google.

Добавить темный режим на страницу JD.com

Каталог выглядит следующим образом

add-dark-to-page
├
├─README.md
├─manifest.json
├─js
| ├─background.js
| └home.js
├─images
|   └icon.png
├─html
|  ├─home.html
|  └options.html
├─css
|  └index.css

Сначала создайтеmainfest.json

{
  "name": "TimeStone1",
  "manifest_version": 2,
  "version": "1.0",
  "description": "TimeStone 扩展程序",
  "page_action": {
    "default_icon": "images/icon.png",
    "default_title": "TimeStone 插件",
    "default_popup": "html/home.html"
  },
  "background": {
    "scripts": ["js/background.js"]
  },
  "options_page": "html/options.html",
  "homepage_url": "https://juejin.cn/user/4230576473387773",
  "permissions": ["tabs", "activeTab", "declarativeContent"]
}

мышление в темном режиме

我这里的暗黑模式主要是通过 css 的 filter 属性,来控制页面显示。 СпецифическийПроверить

Откройте хром://расширения/

И загрузите распакованное расширение, конкретная операция выглядит следующим образом.

Создайте /background.js в файлах home.html и js.

  • home.html
<!DOCTYPE html>
<html>
  <head>
    <title>TimeStone 插件 home 页面</title>
    <meta charset="utf-8" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link type="text/css" rel="stylesheet" href="../css/index.css" />
  </head>
  <body>
    <div class="time-stone">
      <button class="time-stone_btn" id="ChangeBg">暗黑模式</button>
      <script src="../js/home.js" type="text/javascript"></script>
    </div>
  </body>
</html>

  • home.js
/**
 * 获取URL
 */
function getCurrentTabUrl(callback) {
  let queryInfo = {
    active: true,
    currentWindow: true,
  }

  chrome.tabs.query(queryInfo, (tabs) => {
    let tab = tabs[0]
    let url = tab.url
    console.assert(typeof url === 'string', 'tab.url should be a string')
    callback(url)
  })
}

/**
 *改变当前页面的背景颜色。
 *
 */
function changeBackgroundStyle() {
  const script = 'document.body.style.filter = "grayscale(1)";'
  // See https://developer.chrome.com/extensions/tabs#method-executeScript.
  // 向页面注入JavaScript代码.
  chrome.tabs.executeScript({
    code: script,
  })
}
// 插件会先加载用户上次选择的颜色,如果存在的话。
document.addEventListener('DOMContentLoaded', () => {
  getCurrentTabUrl((url) => {
    // 更改 背景颜色
    ChangeBg.addEventListener('click', function () {
      changeBackgroundStyle()
    })
  })
})

  • background.js
chrome.runtime.onInstalled.addListener(function () {
  // Replace all rules ...
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function () {
    // With a new rule ...
    chrome.declarativeContent.onPageChanged.addRules([
      {
        // That fires when a page's URL contains a 'g' ...
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { urlContains: 'jd.com' },
          }),
        ],
        // And shows the extension's page action.
        actions: [new chrome.declarativeContent.ShowPageAction()],
      },
    ])
  })
})

Адрес источника

Возникла проблема с отладкой вышеуказанного кода, пожалуйста, оставьте сообщение или поднимите вопрос, спасибо!

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