原生訊息傳遞

擴充功能和應用程式可以使用類似於下方的 API,與原生應用程式交換訊息 其他訊息傳遞 API。支援這項功能的原生應用程式必須註冊 內建訊息傳遞主機。Chrome 會在以下位置啟動主機: 獨立程序,並使用標準輸入和標準輸出串流與程序通訊。

內建訊息傳遞主機

如要註冊內建訊息傳遞主機,應用程式必須安裝資訊清單檔案 會定義原生訊息傳遞主機設定以下是資訊清單檔案的範例:

{
  "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內建訊息傳遞主機的名稱。用戶端會將這個字串傳送至 runtime.connectNativeruntime.sendNativeMessage。這個名稱只能包含小寫英數字元、底線和半形句號。名稱的開頭或結尾不得為半形句號,且半形句號的後方不得含有其他點。
description簡短的應用程式說明。
path原生訊息傳遞主機二進位檔的路徑。在 Linux 和 OSX 上,路徑必須是絕對路徑。在 Windows 中,這個檔案可以和資訊清單檔案所在的目錄相對。主機程序會從目前設定為包含主機二進位檔的目錄啟動主機程序。舉例來說,如果這個參數設為 C:\Application\nm_host.exe,則會從目前的目錄 C:\Application\ 開始。
type用來與內建訊息傳遞主機通訊的介面類型,這個參數目前只有一個可能的值:stdio。這表示 Chrome 應使用 stdinstdout 與主機通訊。
allowed_origins應可存取內建訊息傳遞主機的擴充功能清單。不允許使用 chrome-extension://*/* 等萬用字元。

內建訊息傳遞主機位置

資訊清單檔案的位置視平台而定。

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 位元 註冊資料庫

OS XLinux 中,原生訊息傳遞主機的資訊清單檔案位置會因 (Google Chrome 或 Chromium)。調查整個系統的原生訊息傳遞主機 位置,而使用者層級的內建訊息傳遞主機會查詢位於 名為 NativeMessagingHosts使用者個人資料目錄

  • OS X (整個系統)
    • Google Chrome:/Library/Google/Chrome/NativeMessagingHosts/_com.my_company.my_application_.json
    • Chromium:/Library/Application Support/Chromium/NativeMessagingHosts/_com.my_company.my_application_.json
  • OS X (使用者專屬的預設路徑)
    • Google Chrome:~/Library/Application Support/Google/Chrome/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
    • 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
    • Chromium:~/.config/chromium/NativeMessagingHosts/_com.my_company.my_application_.json

內建訊息傳遞通訊協定

Chrome 會以獨立的程序啟動每個內建訊息傳遞主機,並使用 標準輸入內容 (stdin) 和標準輸出內容 (stdout)。使用此格式在 雙向:每封郵件都會採用 JSON 和 UTF-8 編碼,並加上 32 位元 訊息長度與原生位元組順序排列原生訊息中單一訊息的大小上限 主機為 1 MB,主要用於防止 Chrome 運作異常。資訊卡的大小上限 則傳送給內建訊息傳遞主機的訊息大小為 4 GB。

原生訊息傳遞主機的第一個引數是呼叫端的來源,通常是 chrome-extension://[ID of allowed extension]。如此一來,內建訊息傳遞主機就能識別 您所指定的多個副檔名時,系統會在訊息來源的 allowed_origins 鍵 (位於 內建訊息傳遞主機資訊清單警告:在 Windows 中,Chrome 54 以下版本會將來源做為第二個參數傳遞 而不是第一個參數

使用 runtime.connectNative 建立訊息通訊埠時,Chrome 會啟動原生訊息傳遞 並繼續執行,直到通訊埠刪除為止。另一方面,如果收到 使用 runtime.sendNativeMessage 傳送,但沒有建立訊息通訊埠,Chrome 會啟動新的 原生訊息傳遞主機程序如果是主機產生的第一則訊息 處理程序會回應原始要求,例如 Chrome 會將該要求傳送至 呼叫 runtime.sendNativeMessage 時指定的回呼。生成的所有其他訊息 在這種情況下,系統會忽略原生訊息傳遞主機。

在 Windows 上,原生訊息傳遞主機也會傳送指令列引數,其中包含一個控制代碼 呼叫 Chrome 原生視窗:--parent-window=<decimal handle value>。這樣一來 訊息主機會建立正確的原生 UI 視窗。請注意,這個值會是 如果呼叫情境是背景指令碼頁面,則為 0。

連線至原生應用程式

與原生應用程式收發訊息的方式與跨擴充功能十分相似 傳送訊息主要差異在於,系統會改用 runtime.connectNative 使用 runtime.connectruntime.sendNativeMessage runtime.sendMessage. 這些方法只有在「nativeMessaging」下才能使用當應用程式的商店資訊宣告權限時 資訊清單檔案

下列範例會建立連線至原生訊息傳遞主機的 runtime.Port 物件 com.my_company.my_application,開始監聽來自該通訊埠的訊息,並傳送一則傳出訊息 訊息:

var port = chrome.runtime.connectNative('com.my_company.my_application');
port.onMessage.addListener(function(msg) {
  console.log("Received" + msg);
});
port.onDisconnect.addListener(function() {
  console.log("Disconnected");
});
port.postMessage({ text: "Hello, my_application" });

runtime.sendNativeMessage 可用來傳送訊息至原生應用程式,無須建立 通訊埠,例如

chrome.runtime.sendNativeMessage('com.my_company.my_application',
  { text: "Hello" },
  function(response) {
    console.log("Received " + response);
  });

對內建訊息功能偵錯

當內建訊息傳遞主機無法啟動時,請寫入 stderr 或違反 通訊協定會將輸出內容寫入 Chrome 的錯誤記錄。在 Linux 和 OS X 中, 只需透過指令列啟動 Chrome,就能在 終端機。在 Windows 上,按照「如何啟用記錄功能」一文的說明使用 --enable-logging

以下是解決問題的部分錯誤和提示:

  • 無法啟動內建訊息傳遞主機。
    • 確認您是否有足夠的權限可以執行檔案。
  • 指定的內建訊息傳遞主機名稱無效。
    • 檢查名稱是否包含任何無效字元。只能使用小寫英數字元 可以使用底線和半形句號。名稱的開頭或結尾不得為半形句號,且半形句號不得 後面接著一個點
  • 原生主機已關閉。
    • Chrome 讀取訊息前,內建訊息傳遞主機的管道已損毀。大部分 可能是透過原生訊息傳遞主機發起的
  • 找不到指定的內建訊息傳遞主機。
    • 擴充功能和資訊清單檔案中的名稱拼寫是否正確?
    • 資訊清單是否位於正確的目錄中?名稱是否正確?請參閱內建訊息傳遞主機 位置
    • 資訊清單檔案的格式是否正確?尤其是 JSON 語法是否正確 值是否符合原生訊息傳遞主機資訊清單的定義?
    • path 中指定的檔案是否存在?在 Windows 中,路徑可能是相對路徑 在 OS X 和 Linux 中 路徑必須是絕對路徑
  • 未註冊內建訊息傳遞主機主機名稱。(僅適用於 Windows)
    • 在 Windows 登錄中找不到內建訊息傳遞主機。使用 regedit 再次檢查 此鍵是否確實建立,並且符合原生資料庫所述的必要格式 訊息主機位置
  • 系統禁止存取指定的內建訊息傳遞主機。
    • 擴充功能的來源是否列在「allowed_origins」中?
  • 與內建訊息傳遞主機通訊時發生錯誤。
    • 這是相當常見的錯誤,代表通訊協定實作不正確 原生訊息傳遞主機中的
    • 請確認 stdout 中的所有輸出內容都符合原生訊息傳遞通訊協定。如果您希望 如要輸出部分資料以便偵錯,請寫入 stderr
    • 確認 32 位元訊息長度採用平台的原生整數格式 (小端序) / big-endian)。
    • 訊息長度不得超過 1024*1024。
    • 訊息大小必須等於訊息中的位元組數。可能與 「length」,因為字元可能會由多個位元組表示。
    • 僅限 Windows:請確認程式的 I/O 模式已設為 O_BINARY。根據預設 模式為 O_TEXT,將以換行符號 (\n = 0A) 取代訊息格式。 Windows 樣式行結尾 (\r\n = 0D 0A)。您可以使用 __setmode 設定 I/O 模式。