Скрипты контента — это файлы, которые запускаются в контексте веб-страниц. Используя стандартную объектную модель документа (DOM), они могут считывать информацию о веб-страницах, которые посещает браузер, вносить в них изменения и передавать информацию своему родительскому расширению.
Понимание возможностей сценария контента
 Скрипты контента могут получать доступ к API Chrome, используемым их родительским расширением, путем обмена сообщениями с расширением. Они также могут получить доступ к URL-адресу файла расширения с помощью chrome.runtime.getURL() и использовать результат так же, как и другие URL-адреса.
// Code for displaying EXTENSION_DIR/images/myimage.png:
var imgURL = chrome.runtime.getURL("images/myimage.png");
document.getElementById("someImage").src = imgURL;
Кроме того, скрипт контента может напрямую обращаться к следующим API Chrome:
Сценарии контента не могут напрямую обращаться к другим 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);
Оба предупреждения появятся, если кнопка будет нажата.
Изолированные миры не позволяют сценариям содержимого, расширениям и веб-страницам получать доступ к каким-либо переменным или функциям, созданным другими. Это также дает сценариям содержимого возможность включать функции, которые не должны быть доступны на веб-странице.
Внедрить скрипты
Сценарии содержимого можно внедрять программно или декларативно .
Внедрить программно
Используйте программное внедрение для сценариев контента, которые необходимо запускать в определенных случаях.
Чтобы внедрить сценарий программного контента, предоставьте разрешение 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{: #matches } |  | Необходимый. Указывает, на какие страницы будет внедрен этот скрипт содержимого. Дополнительные сведения о синтаксисе этих строк см. в разделе «Шаблоны сопоставления» , а также «Шаблоны сопоставления и глобусы» для получения информации о том, как исключить URL-адреса. | 
| css{: #css } |  | Необязательный. Список файлов CSS, которые будут вставлены в соответствующие страницы. Они вводятся в том порядке, в котором они появляются в этом массиве, до того, как будет создан или отображен какой-либо DOM для страницы. | 
| js{: #js } |  | Необязательный. Список файлов JavaScript, которые будут внедрены на соответствующие страницы. Они вводятся в том порядке, в котором они появляются в этом массиве. | 
| match_about_blank{: #match_about_blank } | логическое значение | Необязательный. Должен ли сценарий внедриться в кадр about:blank, где родительский или открывающий кадр соответствует одному из шаблонов, объявленных вmatches. По умолчанию установлено значениеfalse. | 
Исключить совпадения и глобусы
Указанное соответствие страниц можно настроить, включив следующие поля в регистрацию манифеста.
| Имя | Тип | Описание | 
|---|---|---|
| exclude_matches{: #exclude_matches } |  | Необязательный. Исключает страницы, в которые в противном случае был бы внедрен этот сценарий содержимого. Дополнительные сведения о синтаксисе этих строк см. в разделе «Шаблоны совпадений» . | 
| include_globs{: #include_globs } |  | Необязательный. Применяется после matches, чтобы включать только те URL-адреса, которые также соответствуют этому шаблону. Предназначен для эмуляции ключевого слова@includeGreasemonkey. | 
| exclude_globs{: #exclude_globs } |  | Необязательный. Применяется после matches, чтобы исключить URL-адреса, соответствующие этому шаблону. Предназначен для эмуляции ключевого слова@excludeGreasemonkey. | 
 Скрипт содержимого будет внедрен на страницу, если его URL-адрес соответствует любому шаблону matches и любому шаблону include_globs , если URL-адрес также не соответствует шаблону exclude_matches или exclude_globs .
 Поскольку свойство matches является обязательным, exclude_matches , include_globs и exclude_globs можно использовать только для ограничения того, какие страницы будут затронуты.
Следующее расширение внедрит сценарий содержимого в http://www.nytimes.com/ health , но не в http://www.nytimes.com/ business .
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}
Свойства Glob имеют другой, более гибкий синтаксис, чем шаблоны сопоставления . Допустимыми glob-строками являются URL-адреса, которые могут содержать подстановочные знаки и звездочки. Звездочка * соответствует любой строке любой длины, включая пустую строку, а вопросительный знак ? соответствует любому отдельному символу.
Например, глоб http:// ??? .example.com/foo/ * соответствует любому из следующих значений:
- http://www.example.com/foo/bar
- http://.example.com/foo/
Однако он не соответствует следующему:
- http://мой .example.com/foo/bar
- http:// пример .com/foo/
- http://www.example.com/foo
Это расширение будет вставлять сценарий содержимого в http:/www.nytimes.com/arts/index.html и http://www.nytimes.com/jobs/index.html, но не в http://www.nytimes.com. /спорт/index.html .
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "include_globs": ["*nytimes.com/???s/*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}
Это расширение будет вставлять сценарий содержимого в http:// History .nytimes.com и http://.nytimes.com/ History , но не в http:// science .nytimes.com или http://www.nytimes.com. / наука .
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "exclude_globs": ["*science*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}
Для достижения правильной области действия можно включить один, все или некоторые из них.
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "exclude_matches": ["*://*/*business*"],
      "include_globs": ["*nytimes.com/???s/*"],
      "exclude_globs": ["*science*"],
      "js": ["contentScript.js"]
    }
  ],
  ...
}
Время выполнения
 Время внедрения файлов JavaScript на веб-страницу контролируется полем run_at . Предпочтительным полем по умолчанию является "document_idle" , но при необходимости его также можно указать как "document_start" или "document_end" . 
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "run_at": "document_idle",
      "js": ["contentScript.js"]
    }
  ],
  ...
}
| Имя | Тип | Описание | 
|---|---|---|
| document_idle{: #document_idle } | нить | Предпочтительно. Используйте "document_idle"когда это возможно.Браузер выбирает время для внедрения скриптов между "document_end"и сразу после срабатывания событияwindowonload. Точный момент внедрения зависит от того, насколько сложен документ и сколько времени занимает его загрузка, и оптимизирован под скорость загрузки страницы.Сценариям содержимого, работающим в "document_idle"не нужно прослушивать событиеwindow.onload, они гарантированно запускаются после завершения DOM. Если сценарий обязательно должен быть запущен послеwindow.onload, расширение может проверить, запущена ли ужеonload, используя свойствоdocument.readyState. | 
| document_start{: #document_start } | нить | Скрипты вводятся после любых файлов из css, но до создания любого другого DOM или запуска любого другого скрипта. | 
| document_end{: #document_end } | нить | Скрипты внедряются сразу после завершения DOM, но до загрузки подресурсов, таких как изображения и фреймы. | 
Укажите рамки
 Поле "all_frames" позволяет расширению указать, следует ли вставлять файлы JavaScript и CSS во все кадры, соответствующие указанным требованиям URL-адреса, или только в самый верхний кадр на вкладке. 
{
  "name": "My extension",
  ...
  "content_scripts": [
    {
      "matches": ["http://*.nytimes.com/*"],
      "all_frames": true,
      "js": ["contentScript.js"]
    }
  ],
  ...
}
| Имя | Тип | Описание | 
|---|---|---|
| all_frames{: #all_frames } | логическое значение | Необязательный. По умолчанию установлено значение false, что означает, что сопоставляется только верхний кадр.Если указано true, он будет вставлен во все кадры, даже если этот кадр не является самым верхним кадром на вкладке. Каждый кадр проверяется независимо на соответствие требованиям URL-адреса. Он не будет вставляться в дочерние кадры, если требования URL-адреса не выполняются. | 
Связь со страницей встраивания
Хотя среды выполнения сценариев контента и страниц, на которых они размещены, изолированы друг от друга, они имеют общий доступ к DOM страницы. Если страница желает взаимодействовать со сценарием содержимого или с расширением через сценарий содержимого, она должна делать это через общий DOM.
 Пример можно реализовать с помощью window.postMessage : 
var port = chrome.runtime.connect();
window.addEventListener("message", function(event) {
  // We only accept messages from ourselves
  if (event.source != window)
    return;
  if (event.data.type && (event.data.type == "FROM_PAGE")) {
    console.log("Content script received: " + event.data.text);
    port.postMessage(event.data.text);
  }
}, false);
document.getElementById("theButton").addEventListener("click",
    function() {
  window.postMessage({ type: "FROM_PAGE", text: "Hello from the webpage!" }, "*");
}, false);
Страница без расширения, example.html, отправляет сообщения самому себе. Это сообщение перехватывается и проверяется сценарием содержимого, а затем отправляется в процесс расширения. Таким образом, страница устанавливает канал связи с процессом расширения. Обратное возможно с помощью аналогичных средств.
Оставайтесь в безопасности
Хотя изолированные миры обеспечивают уровень защиты, использование сценариев содержимого может создать уязвимости в расширении и веб-странице. Если сценарий контента получает контент с отдельного веб-сайта, например, создавая XMLHttpRequest , будьте осторожны, чтобы фильтровать атаки с использованием межсайтовых сценариев контента перед его внедрением. Общайтесь только через HTTPS, чтобы избежать атак «человек посередине» .
Обязательно отфильтруйте вредоносные веб-страницы. Например, опасны следующие шаблоны:
var data = document.getElementById("json-data")
// WARNING! Might be evaluating an evil script!
var parsed = eval("(" + data + ")")
var elmt_id = ...
// WARNING! elmt_id might be "); ... evil script ... //"!
window.setTimeout("animate(" + elmt_id + ")", 200);
Вместо этого отдайте предпочтение более безопасным API, которые не запускают скрипты:
var data = document.getElementById("json-data")
// JSON.parse does not evaluate the attacker's scripts.
var parsed = JSON.parse(data);
var elmt_id = ...
// The closure form of setTimeout does not evaluate scripts.
window.setTimeout(function() {
  animate(elmt_id);
}, 200);