ส่วนขยายสามารถแลกเปลี่ยนข้อความกับแอปพลิเคชันดั้งเดิมได้โดยใช้ 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/"]
}
ไฟล์ Manifest ของโฮสต์การรับส่งข้อความในเครื่องต้องเป็น JSON ที่ถูกต้องและมีช่องต่อไปนี้
name- ชื่อของโฮสต์การรับส่งข้อความในเครื่อง ไคลเอ็นต์จะส่งสตริงนี้ไปยัง
runtime.connectNative()หรือruntime.sendNativeMessage()ชื่อนี้มีได้เฉพาะอักขระที่เป็นตัวอักษรและตัวเลขคละกันพิมพ์เล็ก ขีดล่าง และจุด ชื่อต้องไม่ขึ้นต้นหรือลงท้ายด้วยจุด และจุดต้องไม่ตามด้วยจุดอีกจุด description- คำอธิบายแอปพลิเคชันแบบย่อ
path- เส้นทางไปยังไบนารีของโฮสต์การรับส่งข้อความในเครื่อง ใน Linux และ macOS เส้นทางต้องเป็นค่าสัมบูรณ์ ใน Windows เส้นทางนี้อาจสัมพันธ์กับไดเรกทอรีที่มีไฟล์ Manifest กระบวนการโฮสต์จะเริ่มต้นโดยตั้งค่าไดเรกทอรีปัจจุบันเป็นไดเรกทอรีที่มีไบนารีของโฮสต์ เช่น หากตั้งค่าพารามิเตอร์นี้เป็น
C:\Application\nm_host.exeระบบจะเริ่มต้นด้วยไดเรกทอรีปัจจุบัน `C:\Application` type- ประเภทของอินเทอร์เฟซที่ใช้ในการสื่อสารกับโฮสต์การรับส่งข้อความในเครื่อง พารามิเตอร์นี้มีค่าที่เป็นไปได้ค่าเดียวคือ
stdioซึ่งระบุว่า Chrome ควรใช้stdinและstdoutเพื่อสื่อสารกับโฮสต์ allowed_origins- รายการส่วนขยายที่ควรมีสิทธิ์เข้าถึงโฮสต์การรับส่งข้อความในเครื่อง ค่า
allowed_originsต้องไม่มีไวลด์การ์ด
ตำแหน่งโฮสต์การรับส่งข้อความในเครื่อง
ตำแหน่งของไฟล์ Manifest จะขึ้นอยู่กับแพลตฟอร์ม
ใน Windows คุณวางไฟล์ Manifest ไว้ที่ใดก็ได้ในระบบไฟล์ โปรแกรมติดตั้งแอปพลิเคชัน
ต้องสร้างคีย์รีจิสทรี ไม่ว่าจะเป็น
HKEY_LOCAL_MACHINE\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application หรือ
HKEY_CURRENT_USER\SOFTWARE\Google\Chrome\NativeMessagingHosts\com.my_company.my_application และ
ตั้งค่าเริ่มต้นของคีย์นั้นเป็นเส้นทางแบบเต็มไปยังไฟล์ Manifest เช่น ใช้คำสั่งต่อไปนี้
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 บิต
ใน macOS และ Linux ตำแหน่งของไฟล์ Manifest ของโฮสต์การรับส่งข้อความในเครื่องจะแตกต่างกันไปตามเบราว์เซอร์ (Google Chrome, Chrome สำหรับการทดสอบ หรือ Chromium) ระบบจะค้นหาโฮสต์การรับส่งข้อความที่มาพร้อมระบบทั่วทั้งระบบในตำแหน่งที่แน่นอน
ส่วนโฮสต์การรับส่งข้อความที่มาพร้อมระบบระดับผู้ใช้จะค้นหาในNativeMessagingHosts/ไดเรกทอรีย่อย
ของไดเรกทอรีโปรไฟล์ผู้ใช้
- 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) ระบบจะใช้รูปแบบเดียวกันในการส่งข้อความในทั้ง 2 ทิศทาง โดยจะมีการเรียงอันดับข้อความแต่ละรายการโดยใช้ JSON, เข้ารหัส UTF-8 และนำหน้าด้วยความยาวของข้อความ 32 บิตในลำดับไบต์ดั้งเดิม ขนาดสูงสุดของข้อความเดียวจากโฮสต์การรับส่งข้อความดั้งเดิมคือ 1 MB ซึ่งส่วนใหญ่มีไว้เพื่อปกป้อง Chrome จากแอปพลิเคชันดั้งเดิมที่ทำงานไม่ถูกต้อง ขนาดสูงสุดของ
ข้อความที่ส่งไปยังโฮสต์การรับส่งข้อความในเครื่องคือ 64 MiB
อาร์กิวเมนต์แรกของโฮสต์การรับส่งข้อความในเครื่องคือต้นทางของผู้เรียก ซึ่งโดยปกติคือ
chrome-extension://[ID of allowed extension] ซึ่งจะช่วยให้โฮสต์การรับส่งข้อความในเครื่องระบุแหล่งที่มาของข้อความได้เมื่อมีการระบุส่วนขยายหลายรายการในคีย์ allowed_origins ในไฟล์ Manifest ของโฮสต์การรับส่งข้อความในเครื่อง
ใน Windows โฮสต์การรับส่งข้อความในเครื่องจะได้รับอาร์กิวเมนต์บรรทัดคำสั่งที่มีแฮนเดิลไปยัง
หน้าต่างในเครื่องของ Chrome ที่เรียกใช้ด้วย --parent-window=<decimal handle value> ซึ่งจะช่วยให้โฮสต์การรับส่งข้อความในเครื่องสร้างหน้าต่าง UI ในเครื่องที่เชื่อมโยงกับองค์ประกอบหลักได้อย่างถูกต้อง โปรดทราบว่าค่านี้จะเป็น
0 หากบริบทการเรียกเป็น Service Worker
เมื่อสร้างพอร์ตการรับส่งข้อความโดยใช้ runtime.connectNative() Chrome จะเริ่มกระบวนการโฮสต์การรับส่งข้อความดั้งเดิม
และจะเรียกใช้กระบวนการนี้ต่อไปจนกว่าจะทำลายพอร์ต ในทางกลับกัน เมื่อส่งข้อความโดยใช้ runtime.sendNativeMessage() โดยไม่ได้สร้างพอร์ตการรับส่งข้อความ Chrome จะเริ่มกระบวนการโฮสต์การรับส่งข้อความในเครื่องใหม่สำหรับแต่ละข้อความ ในกรณีดังกล่าว ระบบจะจัดการข้อความแรกที่โฮสต์สร้างขึ้น
เป็นคำตอบสำหรับคำขอเดิม และ Chrome จะส่งข้อความนั้นไปยังการเรียกกลับการตอบกลับ
ที่ระบุเมื่อมีการเรียกใช้ runtime.sendNativeMessage() ระบบจะไม่สนใจข้อความอื่นๆ ทั้งหมดที่โฮสต์การรับส่งข้อความในเครื่องสร้างขึ้นในกรณีดังกล่าว
การเชื่อมต่อกับแอปพลิเคชันแบบเนทีฟ
การส่งและรับข้อความไปยังและจากแอปพลิเคชันแบบเนทีฟจะคล้ายกับการรับส่งข้อความข้ามส่วนขยายเป็นอย่างมาก ความแตกต่างหลักคือใช้ runtime.connectNative() แทน
runtime.connect() และใช้ runtime.sendNativeMessage() แทน
runtime.sendMessage()
หากต้องการใช้วิธีการเหล่านี้ คุณต้องประกาศสิทธิ์ "nativeMessaging" ในไฟล์ Manifest ของส่วนขยาย
วิธีการเหล่านี้ใช้ไม่ได้ภายใน Content Script แต่ใช้ได้เฉพาะภายในหน้าเว็บและ Service Worker ของส่วนขยาย หากต้องการสื่อสารจาก Content Script ไปยังแอปพลิเคชันแบบเนทีฟ ให้ส่งข้อความไปยัง Service Worker เพื่อส่งต่อข้อความไปยังแอปพลิเคชันแบบเนทีฟ
ตัวอย่างต่อไปนี้สร้างออบเจ็กต์ runtime.Port ที่เชื่อมต่อกับโฮสต์การรับส่งข้อความในเครื่อง
com.my_company.my_application เริ่มฟังข้อความจากพอร์ตนั้น และส่งข้อความขาออก
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 ที่มีอยู่
หากต้องการดูเอาต์พุต ให้สตรีม chrome_debug.log โดยใช้ PowerShell ดังนี้
$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 ได้ด้วย
รายละเอียดการบันทึกที่สำคัญ
- ระบบจะบันทึกการค้นหาและการแยกวิเคราะห์ไฟล์ Manifest ที่ล้มเหลวใน
launch_context.ccเป็นคำเตือน ใช้--log-level=1แทน2(ข้อผิดพลาด) ซึ่งจะระงับการวินิจฉัยการเริ่มต้นเหล่านี้ - ค้นหา
launch_contextเพื่อหาข้อผิดพลาดในการเปิดใช้ไฟล์ Manifest และไบนารี และnative_messagเพื่อหาข้อผิดพลาดเกี่ยวกับขนาดเพย์โหลดและการสื่อสารผ่านไปป์
ข้อผิดพลาดที่พบบ่อย
ข้อผิดพลาดที่พบบ่อยและเคล็ดลับในการแก้ไขมีดังนี้
เริ่มโฮสต์การรับส่งข้อความในเครื่องไม่สำเร็จ
ตรวจสอบว่าคุณมีสิทธิ์เพียงพอที่จะเรียกใช้ไฟล์โฮสต์การรับส่งข้อความในเครื่องหรือไม่
ระบุชื่อโฮสต์การรับส่งข้อความในเครื่องไม่ถูกต้อง
ตรวจสอบว่าชื่อมีอักขระที่ไม่ถูกต้องหรือไม่ อนุญาตให้ใช้เฉพาะอักขระที่เป็นตัวอักษรพิมพ์เล็กและตัวเลขคละกัน ขีดล่าง และจุดเท่านั้น ชื่อต้องไม่ขึ้นต้นหรือลงท้ายด้วยจุด และจุดต้องไม่ ตามด้วยจุดอีก
โฮสต์ดั้งเดิมออกจากการประชุมแล้ว
การเชื่อมต่อกับโฮสต์การรับส่งข้อความในเครื่องขาดหายไปก่อนที่ Chrome จะอ่านข้อความ ซึ่งส่วนใหญ่ มักจะเริ่มจากโฮสต์การรับส่งข้อความในเครื่องของคุณ
ไม่พบโฮสต์การรับส่งข้อความในเครื่องที่ระบุ
โปรดตรวจสอบสิ่งต่อไปนี้
- ชื่อสะกดถูกต้องในส่วนขยายและในไฟล์ Manifest หรือไม่
- ใน Windows มีคีย์รีจิสทรีอยู่ภายใต้
HKEY_CURRENT_USERหรือHKEY_LOCAL_MACHINEและค่าเริ่มต้นของคีย์ชี้ไปยังเส้นทางแบบเต็มของไฟล์ Manifest หรือไม่ Chrome จะค้นหามุมมองรีจิสทรีแบบ 32 บิตก่อน แล้วจึงค้นหามุมมองแบบ 64 บิต ใช้regeditเพื่อยืนยันคีย์ ดูตำแหน่งโฮสต์การรับส่งข้อความในเครื่อง - ใน macOS และ Linux ไฟล์ Manifest อยู่ในไดเรกทอรีที่คาดไว้
และมีชื่อตามโฮสต์ (เช่น
com.my_company.my_application.json) หรือไม่ ดูตำแหน่งโฮสต์การรับส่งข้อความในเครื่อง - ไฟล์ Manifest อยู่ในรูปแบบที่ถูกต้องหรือไม่ โดยเฉพาะอย่างยิ่ง JSON ถูกต้องและมีรูปแบบที่ถูกต้องหรือไม่ และค่าต่างๆ ตรงกับคำจำกัดความของ Manifest ของโฮสต์การรับส่งข้อความในเครื่องหรือไม่
- มีไฟล์ที่ระบุใน
pathหรือไม่ ใน Windows เส้นทางอาจเป็นแบบสัมพัทธ์ แต่ใน macOS และ Linux เส้นทางต้องเป็นแบบสัมบูรณ์
ไม่อนุญาตให้เข้าถึงโฮสต์การรับส่งข้อความในเครื่องที่ระบุ
ต้นทางของส่วนขยายแสดงอยู่ใน allowed_origins หรือไม่
เกิดข้อผิดพลาดเมื่อสื่อสารกับโฮสต์การรับส่งข้อความในเครื่อง
ซึ่งบ่งชี้ว่ามีการติดตั้งใช้งานโปรโตคอลการสื่อสารในโฮสต์การรับส่งข้อความในเครื่องไม่ถูกต้อง
- ตรวจสอบว่าเอาต์พุตทั้งหมดใน
stdoutเป็นไปตามโปรโตคอลการรับส่งข้อความที่มาพร้อมระบบ หากต้องการ พิมพ์ข้อมูลบางอย่างเพื่อวัตถุประสงค์ในการแก้ไขข้อบกพร่อง โปรดเขียนถึงstderr - ตรวจสอบว่าความยาวของข้อความแบบ 32 บิตอยู่ในรูปแบบจำนวนเต็มดั้งเดิมของแพลตฟอร์ม (little-endian / big-endian)
- ความยาวของข้อความต้องไม่เกิน 1024*1024
- ขนาดข้อความต้องเท่ากับจำนวนไบต์ในข้อความ ซึ่งอาจแตกต่างจาก "ความยาว" ของสตริง เนื่องจากอักขระอาจแสดงด้วยหลายไบต์
- Windows เท่านั้น: ตรวจสอบว่าได้ตั้งค่าโหมด I/O ของโปรแกรมเป็น
O_BINARYแล้ว โดยค่าเริ่มต้น โหมด I/O คือO_TEXTซึ่งจะทำให้รูปแบบข้อความเสียหายเนื่องจากระบบจะแทนที่ตัวแบ่งบรรทัด (\n=0A) ด้วย ตัวสิ้นสุดบรรทัดสไตล์ Windows (\r\n=0D 0A) คุณตั้งค่าโหมด I/O ได้โดยใช้__setmode