需求
最近在開發一個小插件,需要實現在Chrome
插件中釣魚python
腳本的功能。
查了一下發現使用Native Message
來實現。
流程
https://developer.chrome.com/extensions/nativeMessaging
看官方文檔,以及官方的例子其實就可以很清楚了。
大概意思就是在本地註冊一個服務,然後插件去調用服務。也就是說我按照要求寫好配置文件,插件調用配置文件裏說好的python
腳本就可以了。
問題記錄
那我遇到了什麼樣的問題呢?
最開始遇到的問題在官方文檔裏也有給出:Failed to start native messaging host.
,就是問沒有執行權限。然後我給腳本加上執行權限之後,就ok了。
問題變成了:Native host has exited.
然後一天多的時間就一直是這個問題…我嘗試了好多,google
搜了好多,搞不清楚。
把官方例子裏的代碼抄抄改改,也還是不行,反正就始終提示這個問題。
然後我又搜到python
是有一個這樣的庫的,就叫nativemessaging
(https://pypi.org/project/nativemessaging/
),直接pip install
就可以安裝…
但是!也不知道怎麼回事,這個會報錯,直接運行下面代碼,
import nativemessaging
while True:
message = nativemessaging.get_message()
nativemessaging.send_message(nativemessaging.encode_message("world"))
會報raw_length = sys.stdin.buffer.read(4) AttributeError: 'file' object has no attribute 'buffer'
錯(好像是這個來着)。我感覺像是這個庫有點老了?但明明是前幾個月纔剛更新過…本來以爲是因爲直接運行腳本,沒有輸入纔會報錯,但是當我從命令行啓動chrome
之後,發現仍然有這樣的報錯信息,就覺得大概真的是不能用吧…
還是老老實實從官方例子下手吧。
(⊙o⊙)…剛開始也還是一直都不行…官方例子裏是開啓了一個線程…我把線程去掉之後,就可以了🤢
可以工作的代碼是這樣:
//background.js
chrome.runtime.sendNativeMessage(
'com.my_company.my_application',
{ text: "Hello" },
function(response) {//收到返回消息後的處理函數
console.log(JSON.stringify(response))
});
//因爲我是想發送一次連一次的,所以沒有建立端口。試過建立端口也是可以正常工作的,代碼也給出來了
//port
connect();
sendNativeMessage();
function connect() {
var hostName = "com.my_company.my_application";
port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}
function sendNativeMessage() {
message = {"text": "a"};
port.postMessage(message);
}
function onNativeMessage(message) {
console.log(JSON.stringify(message))
}
function onDisconnected() {
port = null;
console.log(chrome.runtime.lastError.message);
}
//python
#!/usr/bin/env python
import sys
import struct
import threading
def send_message(message):
# Write message size.
sys.stdout.write(struct.pack('I', len(message)))
# Write the message itself.
sys.stdout.write(message)
sys.stdout.flush()
# Thread that reads messages from the webapp.
def read_thread_func():
message_number = 0
#while 1:去掉了循環,之前看nativemessaging庫說是不建立連接時只需要執行一次就可以了,大概是調用一次執行一次的感覺
# Read the message length (first 4 bytes).
text_length_bytes = sys.stdin.read(4)
if len(text_length_bytes) == 0:
# sys.exit(0)
#continue
sys.exit(0)
# Unpack message length as 4 byte integer.
text_length = struct.unpack('i', text_length_bytes)[0]
# Read the text (JSON object) of the message.
text = sys.stdin.read(text_length).decode('utf-8')
# In headless mode just send an echo message back.
send_message('{"echo": %s}' % text)
def Main():
read_thread_func()
if __name__ == '__main__':
Main()
找了一天多,莫名其妙就好了…(⊙o⊙)…不知道我之前試錯時候到底都試到了哪些情況。
另外,debug
信息真的很重要,之前沒有用命令行開chrome
,一些信息看不到,F12
只能看到Native host has exited.
不是最本質的,導致調試會受阻礙。
好了,我終於可以接着實現功能了。