【问题标题】:Native-Messaging firefox extension example "ping_pong" not working because of TypeError由于 TypeError,本机消息传递 firefox 扩展示例“ping_pong”无法正常工作
【发布时间】:2023-03-09 16:42:01
【问题描述】:

我正在尝试在 Firefox 扩展中使用本机消息。我试图从这个https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging构建示例

我复制/粘贴了所有代码并按照页面上的说明进行了设置,它发送了“Ping”但没有收到“Pong”返回。浏览器控制台说 TypeError: a bytes-like object is required, not 'str'on line 17 in the python application。我能做什么?

我使用 Windows 7 和 python 3.x 网络扩展正在向应用程序发送一个 json 对象,然后应用程序测试长度并 struct.unpacks 消息。如果消息是“ping”,它会尝试 struct.pack 和 json.dumps 响应“pong”,Web 扩展接收该响应作为响应。消息和任何错误都会写入 console.log。

它在示例中说:

请注意,在 Windows 上运行带有 -u 标志的 python 是必需的,

为了保证stdin和stdout是以二进制打开的,而不是

比文字,模式。

我确实设置了 .bat 启动脚本以包含 -u 标志,但似乎 python 仍然将标准输入作为字符串读取,然后在尝试 struct.unpack 时给出 TypeError。

用于发送 ping 的 web-extension 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"))

这是给出 TypeError 的行:

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'

【问题讨论】:

    标签: json python-3.x firefox-addon-webextensions chrome-native-messaging


    【解决方案1】:

    使用 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"))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多