Open gamgi opened 1 year ago
Indeed, the child iframe is able to invoke
tauri commands, but the callbacks are fired on root window instead of the iframe, resulting in Couldn't find callback id ... in window
. This seems like a bug.
The workaround is to use a custom invoke initialization script using tauri::Builder::invoke_system(invoke_initialization_script, ...)
which adds proxies from the parent window to the iframe.
I have a working implementation outlined in this commit.
Hi, just leaving more information here because I'm familiar with the topic. WebKit (macOS and Linux) actually supports an option that makes all invoking be able to happen on a parent or a child, separately. It allows you to create and use callbacks solely on the child frame. Unfortunately Webview2 (Windows) does not support something like this (at the last time I checked which is around Tauri 1.0) and all callbacks get received by the parent. Because of this, the feature is not enabled on WebKit to ensure the same behavior across platforms.
Your solution probably works just fine if the iframe is not sandboxed (I didn't run your repro but that commit diff makes sense) but might break if the sandbox is activated for the iframe. An alternative solution that works with the sandbox is to use postMessage
to communicate between the parent and child. This is actually how the Isolation Pattern is implemented, where the parent IPC potentially sets up communication with the child frame. The key generation and encryption stuff is specific to the Isolation Pattern, but you can see how they are using postMessage
to communicate between them.
Perhaps we could come up with some provided scripts or documentation example to help people implement that for their own iframe children easier.
On a side note, you might be interested in the template feature of serialize-to-javascript
for your solution.
any update on this? We have a scenario with a site with an iFrame. and we need to communicate from child iFrame to the rust layer. Can someone please help with how I can setup Tauri to have the child iFrame-rust communication.
I am only building child iFrame code with Tauri/api. The host site doesn't know anything about tauri
If your iframe and main window have the same domain name, then this may be a good method(Add the following code to the very top of iframe js initialization):
// Override the __TAURI_IPC__ function
window.__TAURI_IPC__ = (args) => {
//The parent window callback points to the child window
window.parent[`_${args.callback}`] = window[`_${args.callback}`];
// Call the function of the parent window
window.parent.__TAURI_IPC__(args);
};
First, Tauri will mount the global window.__TAURI_IPC__
in the main window by default, but there is no such function in the child iframe. However, many of Tauri's APIs are based on the window.__TAURI_IPC__
function to communicate with the Tauri backend, so we need to set a window.__TAURI_IPC__
function for the child iframe.
However, the callback function of the communication is defined in the child iframe, so when the communication ends, the callback
function cannot be found in the parent window, so we need to assign the callback
function of the child iframe to the window object of the parent window.
Describe the bug
I am mounting an iframe ("child") within a Tauri app. I control both the parent and child and they both are rendered via tauri's vite build. Both the parent and the child have access to
window.__TAURI__
and related methods.The problem is that I'm not able to
invoke
handlers from the iframe. Usinginvoke
from the ifram produces the following warning in the developer console:It seems that iframe
invoke
successfully registers callbacks and calls the rust handlers, which are successfully run. However, when rust tries to return the response, the callback is caught by the parent window instead of the iframe. The parent does not have the callbacks registered, hence the warning.Is there some way to get Tauri to work with this setup? One way to go about this would be to prefix the callback handlers by frame or window?
Reproduction
Repro:
npm install
cargo tauri dev
[TAURI] Couldn't find callback id 90962087 in window. This happens when the app is reloaded while Rust is running an asynchronous operation.
Additional verifications:
document.querySelector("#root > div > iframe").contentWindow.__TAURI__
.Expected behavior
I expect the child window to be able to invoke tauri handlers from the iframe and to get a response.
Platform and versions
Environment › OS: Mac OS 10.15.7 X64 › Node.js: 18.12.1 › npm: 8.19.2 › pnpm: Not installed! › yarn: Not installed! › rustup: 1.25.1 › rustc: 1.66.1 › cargo: 1.66.1 › Rust toolchain: 1.66.1-x86_64-apple-darwin
Packages › @tauri-apps/cli [NPM]: 1.2.3 › @tauri-apps/api [NPM]: 1.2.0 › tauri [RUST]: 1.2.4, › tauri-build [RUST]: 1.2.1, › tao [RUST]: 0.15.8, › wry [RUST]: 0.23.4,
App › build-type: bundle › CSP: unset › distDir: ../dist › devPath: http://localhost:1420/ › framework: React › bundler: Vite
App directory structure ├─ node_modules ├─ public ├─ src-tauri ├─ .git ├─ .vscode └─ src
Stack trace
Additional context
No response