Native-Messaging firefox 扩展示例 "ping_pong" 由于 TypeError 而无法正常工作
Native-Messaging firefox extension example "ping_pong" not working because of TypeError
我正在尝试在 Firefox 扩展中使用本机消息传递。我试图从这个 https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging
构建示例
我 copy/pasted 所有代码并完全按照页面上的描述进行设置,它发送 "Ping" 但没有收到 "Pong" 返回。浏览器控制台显示 TypeError: a bytes-like object is required, not 'str'on the line 17 in the python application.我能做什么?
我用windows7和python3.x
Web 扩展正在向应用程序发送一个 json 对象,然后测试长度和 struct.unpacks 消息。如果消息是 "ping",它会尝试 struct.pack 和 json.dumps 响应 "pong",Web 扩展程序会收到该响应作为响应。消息和任何错误都会写入 console.log.
例子中说:
请注意 运行 python 和 -u
标志在 Windows、
上是必需的
为了保证stdin和stdout是二进制打开的,而是
比文字,模式。
我确实设置了 .bat 启动脚本以包含 -u 标志,但似乎 python 仍然将标准输入读取为字符串,然后在尝试 struct.unpack.
用于发送 ping 的网络扩展 background.js:
/*
On startup, connect to the "ping_pong" app.
*/
var port = browser.runtime.connectNative("ping_pong");
/*
Listen for messages from the app.
*/
port.onMessage.addListener((response) => {
console.log("Received: " + response);
});
/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
console.log("Sending: ping");
port.postMessage("ping");
});
python 接收 ping 和发送 pong 的应用程序:
#!/usr/bin/python -u
# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.
import json
import sys
import struct
# Read a message from stdin and decode it.
def get_message():
raw_length = sys.stdin.read(4)
if not raw_length:
sys.exit(0)
message_length = struct.unpack('=I', raw_length)[0]
message = sys.stdin.read(message_length)
return json.loads(message)
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content)
encoded_length = struct.pack('=I', len(encoded_content))
return {'length': encoded_length, 'content': encoded_content}
# Send an encoded message to stdout.
def send_message(encoded_message):
sys.stdout.write(encoded_message['length'])
sys.stdout.write(encoded_message['content'])
sys.stdout.flush()
while True:
message = get_message()
if message == "ping":
send_message(encode_message("pong"))
这是给出类型错误的行:
message_length = struct.unpack('=I', raw_length)[0]
日志应该说:
发送:ping
收到:乒乓
日志实际上说:
发送:ping
stderr output from native app ping_pong: Traceback (most recent call last):
stderr output from native app ping_pong: File "C:\Users\ping_pong\ping_pong.py", line 37, in <module>
stderr output from native app ping_pong: message = get_message()
stderr output from native app ping_pong: File "C:\Users\ping_pong\ping_pong.py", line 17, in get_message
stderr output from native app ping_pong: message_length = struct.unpack('=I', raw_length)[0]
stderr output from native app ping_pong: TypeError: a bytes-like object is required, not 'str'
使用 Python 2 对我来说效果很好(在 Linux 上)。
#!/usr/bin/python2 -u
或
path\to\python2
分别在windows批处理文件中。
要使其在 Python 3 中工作,您需要将编码后的字符串打包到一个结构中(我不知道为什么 - 但它确实有效):
#!/usr/bin/python -u
# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.
import json
import sys
import struct
# Read a message from stdin and decode it.
def get_message():
# use buffer to get bytes
raw_length = sys.stdin.buffer.read(4)
#raise ValueError(raw_length)
if not raw_length:
sys.exit(0)
message_length = struct.unpack('=I', raw_length)[0]
message = sys.stdin.buffer.read(message_length).decode("utf-8")
return json.loads(message)
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content).encode("utf-8")
encoded_length = struct.pack('=I', len(encoded_content))
return {'length': encoded_length, 'content': struct.pack(str(len(encoded_content))+"s",encoded_content)}
# Send an encoded message to stdout.
def send_message(encoded_message):
#raise ValueError(encoded_message)
sys.stdout.buffer.write(encoded_message['length'])
sys.stdout.buffer.write(encoded_message['content'])
sys.stdout.buffer.flush()
while True:
message = get_message()
if message == "ping":
send_message(encode_message("pong"))
我正在尝试在 Firefox 扩展中使用本机消息传递。我试图从这个 https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging
构建示例我 copy/pasted 所有代码并完全按照页面上的描述进行设置,它发送 "Ping" 但没有收到 "Pong" 返回。浏览器控制台显示 TypeError: a bytes-like object is required, not 'str'on the line 17 in the python application.我能做什么?
我用windows7和python3.x Web 扩展正在向应用程序发送一个 json 对象,然后测试长度和 struct.unpacks 消息。如果消息是 "ping",它会尝试 struct.pack 和 json.dumps 响应 "pong",Web 扩展程序会收到该响应作为响应。消息和任何错误都会写入 console.log.
例子中说:
请注意 运行 python 和 -u
标志在 Windows、
上是必需的
为了保证stdin和stdout是二进制打开的,而是
比文字,模式。
我确实设置了 .bat 启动脚本以包含 -u 标志,但似乎 python 仍然将标准输入读取为字符串,然后在尝试 struct.unpack.
用于发送 ping 的网络扩展 background.js:
/*
On startup, connect to the "ping_pong" app.
*/
var port = browser.runtime.connectNative("ping_pong");
/*
Listen for messages from the app.
*/
port.onMessage.addListener((response) => {
console.log("Received: " + response);
});
/*
On a click on the browser action, send the app a message.
*/
browser.browserAction.onClicked.addListener(() => {
console.log("Sending: ping");
port.postMessage("ping");
});
python 接收 ping 和发送 pong 的应用程序:
#!/usr/bin/python -u
# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.
import json
import sys
import struct
# Read a message from stdin and decode it.
def get_message():
raw_length = sys.stdin.read(4)
if not raw_length:
sys.exit(0)
message_length = struct.unpack('=I', raw_length)[0]
message = sys.stdin.read(message_length)
return json.loads(message)
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content)
encoded_length = struct.pack('=I', len(encoded_content))
return {'length': encoded_length, 'content': encoded_content}
# Send an encoded message to stdout.
def send_message(encoded_message):
sys.stdout.write(encoded_message['length'])
sys.stdout.write(encoded_message['content'])
sys.stdout.flush()
while True:
message = get_message()
if message == "ping":
send_message(encode_message("pong"))
这是给出类型错误的行:
message_length = struct.unpack('=I', raw_length)[0]
日志应该说: 发送:ping 收到:乒乓
日志实际上说: 发送:ping
stderr output from native app ping_pong: Traceback (most recent call last):
stderr output from native app ping_pong: File "C:\Users\ping_pong\ping_pong.py", line 37, in <module>
stderr output from native app ping_pong: message = get_message()
stderr output from native app ping_pong: File "C:\Users\ping_pong\ping_pong.py", line 17, in get_message
stderr output from native app ping_pong: message_length = struct.unpack('=I', raw_length)[0]
stderr output from native app ping_pong: TypeError: a bytes-like object is required, not 'str'
使用 Python 2 对我来说效果很好(在 Linux 上)。
#!/usr/bin/python2 -u
或
path\to\python2
分别在windows批处理文件中。
要使其在 Python 3 中工作,您需要将编码后的字符串打包到一个结构中(我不知道为什么 - 但它确实有效):
#!/usr/bin/python -u
# Note that running python with the `-u` flag is required on Windows,
# in order to ensure that stdin and stdout are opened in binary, rather
# than text, mode.
import json
import sys
import struct
# Read a message from stdin and decode it.
def get_message():
# use buffer to get bytes
raw_length = sys.stdin.buffer.read(4)
#raise ValueError(raw_length)
if not raw_length:
sys.exit(0)
message_length = struct.unpack('=I', raw_length)[0]
message = sys.stdin.buffer.read(message_length).decode("utf-8")
return json.loads(message)
# Encode a message for transmission, given its content.
def encode_message(message_content):
encoded_content = json.dumps(message_content).encode("utf-8")
encoded_length = struct.pack('=I', len(encoded_content))
return {'length': encoded_length, 'content': struct.pack(str(len(encoded_content))+"s",encoded_content)}
# Send an encoded message to stdout.
def send_message(encoded_message):
#raise ValueError(encoded_message)
sys.stdout.buffer.write(encoded_message['length'])
sys.stdout.buffer.write(encoded_message['content'])
sys.stdout.buffer.flush()
while True:
message = get_message()
if message == "ping":
send_message(encode_message("pong"))