browser.tabs.sendMessage cannot get the return value of a two-dimensional array
Closed this issue · 2 comments
Describe the bug
I try to use the following code to send a message from background to content and receive a two-dimensional array returned by the content script, but the following code always fails. However, when I change "browser" back to "chrome," it works successfully. How can WXT solve this?
Reproduction
background.ts
let result = await browser.tabs.sendMessage(id, { method: "request", payload: null })
if (result != null) {
debugger
await process(result);
}
content.ts
browser.runtime.onMessage.addListener( (request, sender, sendResponse) => {
if (request.method === 'request') {
if (this.bufferQueue.length > 0) {
let result = this.bufferQueue.shift();
sendResponse(result)
} else {
sendResponse()
}
}
return true
})
Steps to reproduce
No response
System Info
System:
OS: macOS 14.5
CPU: (10) arm64 Apple M1 Max
Memory: 191.95 MB / 64.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.7.0 - /opt/homebrew/bin/node
Yarn: 1.22.17 - /opt/homebrew/bin/yarn
npm: 10.8.2 - /opt/homebrew/bin/npm
pnpm: 8.12.1 - ~/Library/pnpm/pnpm
Browsers:
Chrome: 128.0.6613.120
Edge: 128.0.2739.67
Safari: 17.5
npmPackages:
wxt: ^0.19.9 => 0.19.9
Used Package Manager
npm
Validations
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
Not a bug, the polyfill just behaves a bit differently than you expect. Using chrome for messaging is perfectly fine.
You're also not removing the listener when the content script is invalidated, so during development, old listeners are gonna keep firing first, intercepting the messages and returning undefined
by the looks of it.
// Make sure your callback is NOT async
browser.runtime.onMessage.addListener((request, sender) => {
if (ctx.isInvalidated) return;
if (request.method === 'request') {
if (this.bufferQueue.length > 0) {
let result = this.bufferQueue.shift();
return Promise.resolve(result)
} else {
return Promise.resolve()
}
}
})
Rather than receiving a
sendResponse
callback to send a response,onMessage
listeners simply return a Promise whose resolution value is used as a reply.– https://github.com/mozilla/webextension-polyfill?tab=readme-ov-file#using-the-promise-based-apis
@aklinker1 Thank you very much, it turns out I missed it.
Promise.resolve()
After being modified according to your way, it can work.