Extensions can exchange messages with native applications using an API that is similar to the other message passing APIs . Native applications that support this feature must register a native messaging host that can communicate with the extension. Chrome starts the host in a separate process and communicates with it using standard input and standard output streams.
Нативный мессенджер
Для регистрации собственного хоста обмена сообщениями приложение должно сохранить файл, определяющий конфигурацию собственного хоста обмена сообщениями.
Пример файла выглядит следующим образом:
{
"name": "com.my_company.my_application",
"description": "My Application",
"path": "C:\\Program Files\\My Application\\chrome_native_messaging_host.exe",
"type": "stdio",
"allowed_origins": ["chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/"]
}
Файл манифеста собственного сервера обмена сообщениями должен представлять собой допустимый JSON-файл и содержать следующие поля:
-
name - Name of the native messaging host. Clients pass this string to
runtime.connectNative()orruntime.sendNativeMessage(). This name can only contain lowercase alphanumeric characters, underscores and dots. The name can't start or end with a dot, and a dot can't be followed by another dot. -
description - Краткое описание приложения.
-
path - Путь к исполняемому файлу хоста обмена сообщениями. В Linux и macOS путь должен быть абсолютным. В Windows он может быть относительным к каталогу, содержащему файл манифеста. Процесс хоста запускается с текущим каталогом, установленным на каталог, содержащий исполняемый файл хоста. Например, если этот параметр установлен на
C:\Application\nm_host.exe, то он будет запущен с текущим каталогом `C:\Application`. -
type - Type of the interface used to communicate with the native messaging host. This parameter has one possible value:
stdio. It indicates that Chrome should usestdinandstdoutto communicate with the host. -
allowed_origins - Список расширений, которые должны иметь доступ к собственному хосту обмена сообщениями. Значения
allowed_originsне могут содержать подстановочные знаки.
Местоположение хоста нативного обмена сообщениями
Расположение файла манифеста зависит от платформы.
В Windows файл манифеста может располагаться в любом месте файловой системы. Установщик приложения должен создать ключ реестра, либо HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application , либо HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application , и установить значение по умолчанию для этого ключа равным полному пути к файлу манифеста. Например, используя следующую команду:
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application" /ve /t REG_SZ /d "C:\path\to\nmh-manifest.json" /f
или используя следующий файл .reg :
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Google\Chrome\NativeMessagingHosts\com.my_company.my_application]
@="C:\\path\\to\\nmh-manifest.json"
Когда Chrome ищет собственные хосты для обмена сообщениями, сначала запрашивается 32-битный реестр, а затем 64-битный.
On macOS and Linux , the location of the native messaging host's manifest file varies by the browser (Google Chrome, Google Chrome for Testing or Chromium). The system-wide native messaging hosts are looked up at a fixed location, while the user-level native messaging hosts are looked up in the NativeMessagingHosts/ subdirectory of the user profile directory .
- macOS (в масштабах всей системы)
- Google Chrome:
/Library/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
/Library/Google/ChromeForTesting/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json - macOS (путь по умолчанию , специфичный для пользователя)
- Google Chrome:
~/Library/Application Support/Google/Chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
~/Library/Application Support/Google/ChromeForTesting/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
~/Library/Application Support/Chromium/NativeMessagingHosts/com.my_company.my_application.json - Linux (в масштабах всей системы)
- Google Chrome:
/etc/opt/chrome/native-messaging-hosts/com.my_company.my_application.json - Google Chrome для тестирования:
/etc/opt/chrome_for_testing/native-messaging-hosts/com.my_company.my_application.json - Chromium:
/etc/chromium/native-messaging-hosts/com.my_company.my_application.json - Linux (путь по умолчанию , специфичный для пользователя)
- Google Chrome:
~/.config/google-chrome/NativeMessagingHosts/com.my_company.my_application.json - Google Chrome для тестирования:
~/.config/google-chrome-for-testing/NativeMessagingHosts/com.my_company.my_application.json - Chromium:
~/.config/chromium/NativeMessagingHosts/com.my_company.my_application.json
Собственный протокол обмена сообщениями
Chrome запускает каждый собственный хост обмена сообщениями в отдельном процессе и взаимодействует с ним, используя стандартный ввод ( stdin ) и стандартный вывод ( stdout ). Для отправки сообщений в обоих направлениях используется один и тот же формат; каждое сообщение сериализуется в формате JSON, кодируется в UTF-8 и предваряется 32-битной длиной сообщения в порядке байтов собственного кода. Максимальный размер одного сообщения от собственного хоста обмена сообщениями составляет 1 МБ, главным образом для защиты Chrome от некорректной работы собственных приложений. Максимальный размер сообщения, отправляемого собственному хосту обмена сообщениями, составляет 64 МиБ.
The first argument to the native messaging host is the origin of the caller, usually chrome-extension://[ID of allowed extension] . This allows native messaging hosts to identify the source of the message when multiple extensions are specified in the allowed_origins key in the native messaging host manifest .
On Windows, the native messaging host is also passed a command line argument with a handle to the calling Chrome native window: --parent-window=<decimal handle value> . This lets the native messaging host create native UI windows that are correctly parented. Note that this value will be 0 if the calling context is a service worker.
Когда порт для обмена сообщениями создается с помощью runtime.connectNative() Chrome запускает собственный процесс хоста обмена сообщениями и поддерживает его работу до тех пор, пока порт не будет уничтожен. С другой стороны, когда сообщение отправляется с помощью runtime.sendNativeMessage() без создания порта для обмена сообщениями, Chrome запускает новый собственный процесс хоста обмена сообщениями для каждого сообщения. В этом случае первое сообщение, сгенерированное процессом хоста, обрабатывается как ответ на исходный запрос, и Chrome передаст его в функцию обратного вызова ответа, указанную при вызове runtime.sendNativeMessage() . Все остальные сообщения, сгенерированные собственным процессом хоста обмена сообщениями в этом случае, игнорируются.
Подключение к нативному приложению
Sending and receiving messages to and from a native application is very similar to cross-extension messaging. The main difference is that runtime.connectNative() is used instead of runtime.connect() , and runtime.sendNativeMessage() is used instead of runtime.sendMessage() .
Для использования этих методов необходимо указать разрешение "nativeMessaging" в файле манифеста вашего расширения.
These methods are not available inside content scripts, only inside your extension's pages and service worker. To communicate from a content script to the native application, send the message to your service worker to pass it along to the native application.
The following example creates a runtime.Port object that's connected to native messaging host com.my_company.my_application , starts listening for messages from that port and sends one outgoing message:
const port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener((msg) => {
console.log('Received', msg);
});
port.onDisconnect.addListener(() => {
if (chrome.runtime.lastError) {
console.error(
'Disconnected due to error:',
chrome.runtime.lastError.message
);
} else {
console.log('Disconnected');
}
});
port.postMessage({text: 'Hello, my_application'});
Используйте runtime.sendNativeMessage для отправки сообщения в нативное приложение без создания порта, например:
chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{text: 'Hello'},
(response) => {
if (chrome.runtime.lastError) {
console.error(
'Error sending native message:',
chrome.runtime.lastError.message
);
return;
}
console.log('Received', response);
}
);
Отладка встроенной системы обмена сообщениями
При возникновении сбоев в работе встроенной системы обмена сообщениями диагностическая информация записывается в журнал ошибок Chrome.
Linux и macOS
# Linux
google-chrome --enable-logging=stderr --log-level=1 2>&1 | \
grep -E "native_messag|launch_context"
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--enable-logging=stderr --log-level=1 2>&1 | \
grep -E "native_messag|launch_context"
Windows
Запустите Chrome с включенным логированием :
chrome.exe --enable-logging --log-level=1
Передайте параметр --user-data-dir="%TEMP%\nm-debug" , чтобы запустить отдельный экземпляр без привязки к существующему процессу Chrome.
Чтобы просмотреть вывод, используйте PowerShell для потоковой передачи файла chrome_debug.log :
$log = "$env:LOCALAPPDATA\Google\Chrome\User Data\chrome_debug.log"
Get-Content -Wait $log | Select-String "native_messag|launch_context"
Вы также можете открыть chrome_debug.log в текстовом редакторе и найти там launch_context.cc или native_message_process_host.cc .
Подробности записи нажатия клавиш
- Сбои при поиске и анализе манифеста в
launch_context.ccрегистрируются как предупреждения. Используйте--log-level=1вместо2(ERROR), что подавляет эти диагностические сообщения при запуске. - Найдите
launch_context, чтобы обнаружить ошибки запуска манифеста и бинарного файла, иnative_messagчтобы обнаружить ошибки размера полезной нагрузки и обмена данными по каналу.
Распространенные ошибки
Вот несколько распространенных ошибок и советы по их исправлению:
Не удалось запустить собственный хост обмена сообщениями.
Проверьте, достаточно ли у вас прав для выполнения файла hosts, отвечающего за обмен сообщениями.
Указано недопустимое имя хоста для обмена сообщениями.
Check whether the name contains invalid characters. Only lowercase alphanumeric characters, underscores, and dots are allowed. A name cannot start or end with a dot, and a dot cannot be followed by another dot.
Основной хост завершил работу.
Соединение с нативным мессенджером прервалось до того, как сообщение было прочитано Chrome. Вероятнее всего, это произошло по вине вашего нативного мессенджера.
Указанный собственный хост обмена сообщениями не найден.
Проверьте следующее:
- Правильно ли написано имя в расширении и в файле манифеста?
- On Windows, does the registry key exist under
HKEY_CURRENT_USERorHKEY_LOCAL_MACHINE, and does its default value point to the full manifest path? Chrome queries the 32-bit registry view first, then the 64-bit view. Useregeditto verify the key. See native messaging host location . - В macOS и Linux файл манифеста находится в ожидаемом каталоге и назван в соответствии с именем хоста (например,
com.my_company.my_application.json)? См. раздел «Расположение хоста для обмена сообщениями» . - Соответствует ли файл манифеста правильному формату? В частности, является ли JSON-файл корректным и правильно сформированным, и соответствуют ли значения определению манифеста нативного хоста обмена сообщениями ?
- Существует ли указанный в
pathфайл? В Windows пути могут быть относительными, но в macOS и Linux пути должны быть абсолютными.
Доступ к указанному собственному серверу обмена сообщениями запрещен.
Указан ли источник расширения в файле allowed_origins ?
Ошибка при обмене данными с собственным сервером обмена сообщениями.
Это указывает на некорректную реализацию протокола связи в собственном хосте обмена сообщениями.
- Убедитесь, что весь вывод в
stdoutсоответствует собственному протоколу обмена сообщениями . Если вы хотите вывести какие-либо данные для отладки, записывайте их вstderr. - Убедитесь, что длина 32-битного сообщения указана в собственном целочисленном формате платформы (little-endian / big-endian).
- Длина сообщения не должна превышать 1024*1024.
- Размер сообщения должен быть равен количеству байтов в сообщении. Это может отличаться от «длины» строки, поскольку символы могут быть представлены несколькими байтами.
- Windows-only: Make sure that the program's I/O mode is set to
O_BINARY. By default, the I/O mode isO_TEXT, which corrupts the message format as line breaks (\n=0A) are replaced with Windows-style line endings (\r\n=0D 0A). The I/O mode can be set using__setmode.