Подтвердить что ты не робот

При желании введите Content Script

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

В моем случае использования я хочу ввести gmail, outlook.com и почтовый веб-сайт yahoo без участия пользователя. Я могу сделать, объявив, что все они манифестированы, но при этом требуют доступа всех данных к этой учетной записи. Некоторое использование может хотеть предоставить только outlook.com, но не gmail. Программная инъекция не работает, потому что мне нужно знать, когда вводить. Использование разрешения табуляции также требует другого разрешения.

Есть ли какой-либо хороший способ для опционального ввода веб-сайта?

4b9b3361

Ответ 1

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

В ответ на жест пользователя вы можете использовать chrome.permission.request для запроса дополнительных разрешений. Этот API можно использовать только на дополнительных страницах (справочная страница, всплывающая страница, страница параметров,...). Начиная с Chrome 36.0.1957.0, требуемый жест пользователя также переносится из сценариев контента, поэтому, если вы захотите, вы можете добавить прослушиватель событий клика из содержимого script и использовать chrome.runtime.sendMessage, чтобы отправить запрос на фоновый рисунок, который, в свою очередь, вызывает chrome.permissions.request.

Дополнительное выполнение кода на вкладках

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

  • Используйте chrome.declarativeContent.RequestContentScript действие, чтобы вставить содержимое script на странице. Прочтите документацию, если вы хотите узнать, как использовать этот API.

  • Используйте webNavigation API (например, chrome.webNavigation.onCommitted), чтобы определить, когда пользователь перешел на страницу, а затем chrome.tabs.executeScript, чтобы вставить содержимое script на вкладке (или chrome.tabs.insertCSS для вставки стилей).

  • Используйте tabs API (chrome.tabs.onUpdated), чтобы обнаружить, что страница могла быть изменена, и вставить содержимое script на странице с помощью chrome.tabs.executeScript.

Я настоятельно рекомендую вариант 1, потому что он был специально разработан для этого варианта использования. Примечание. Этот API был добавлен в Chrome 38, но работал только с дополнительными разрешениями с Chrome 39. Несмотря на "ПРЕДУПРЕЖДЕНИЕ: это действие все еще экспериментально и не поддерживается стабильными версиями Chrome. "в документации API фактически поддерживается на стабильной. Первоначально идея заключалась в дождаться пересмотра перед публикацией API на стабильном уровне, но этот обзор никогда не приходило, и теперь этот API работает нормально почти два года.

Второй и третий варианты схожи. Разница между ними заключается в том, что с помощью API webNavigation добавляется дополнительное предупреждение ( "Прочитайте историю просмотров" ). Для этого предупреждения вы получаете API, который может эффективно фильтровать навигацию, поэтому количество вызовов chrome.tabs.executeScript может быть сведено к минимуму.

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

Используя один из двух последних методов, ваш контент script должен быть сконструирован таким образом, чтобы он мог обрабатывать несколько вложений (например, с защитой), Вставка в фреймы также поддерживается (allFrames:true), но только если вашему добавочному номеру разрешен доступ к URL-адресу закладки (или URL-адрес фрейма, если frameId).

Ответ 2

Я разделю это на две части.

Внедрение программного скрипта

Существует новый contentScripts.register() API, который может программно регистрировать скрипты содержимого, и они будут загружены точно так же, как content_scripts, определенный в манифесте:

browser.contentScripts.register({
    matches: ['https://your-dynamic-domain.example.com/*'],
    js: [{file: 'content.js'}]
});

Этот API доступен только в Firefox, но вы можете использовать Chrome polyfill.

Получение новых разрешений

Используя chrome.permissions.request, вы можете добавлять новые домены, в которые вы можете вставлять скрипты контента. Примером может быть:

// In a content script or options page
document.querySelector('button').addEventListener('click', () => {
    chrome.permissions.request({
        origins: ['https://your-dynamic-domain.example.com/*']
    }, granted => {
        if (granted) {
            /* Use contentScripts.register */
        }
    });
});

И вам нужно добавить optional_permissions в свой manifest.json, чтобы разрешить запрашивать новые источники:

{
    "optional_permissions": [
        "http://*/*",
        "https://*/*"
    ]
}

Я также написал несколько инструментов для дальнейшего упрощения этого для вас и для конечного пользователя, таких как webext-domain-permission-toggle и webext-dynamic-content-scripts. Они автоматически зарегистрируют ваши скрипты при следующих запусках браузера и позволят пользователю удалить новые разрешения и скрипты.

Ответ 3

Поскольку существующему ответу уже несколько лет, опциональная инъекция теперь намного проще и описана здесь described here. В нем говорится, что для условного добавления нового файла вы можете использовать следующий код:

// The lines I have commented are in the documentation, but the uncommented
// lines are the important part

//chrome.runtime.onMessage.addListener((message, callback) => {
//   if (message == 'runContentScript'){

        chrome.tabs.executeScript({
          file: 'contentScript.js'
        });

//   }
//});

Для этого вам потребуется разрешение активной вкладки.