Skip to content

fix(web): use srcdoc instead of data: URI in loadData to fix cross-origin restrictions#2792

Open
zenalex wants to merge 3 commits into
pichillilorenzo:masterfrom
zenalex:master
Open

fix(web): use srcdoc instead of data: URI in loadData to fix cross-origin restrictions#2792
zenalex wants to merge 3 commits into
pichillilorenzo:masterfrom
zenalex:master

Conversation

@zenalex

@zenalex zenalex commented Mar 4, 2026

Copy link
Copy Markdown

Summary

  • loadData on web uses data: URI to set iframe content, which creates an iframe with a unique opaque origin (null). This makes the iframe cross-origin with the parent page, silently breaking evaluateJavascript, onConsoleMessage, and other features that rely on contentWindow access.
  • Replaced iframe.src = 'data:...' with iframe.srcdoc = data.toJS, which inherits the parent page's origin and restores same-origin access.

Problem

When using InAppWebView with initialData on web, the following features silently fail:

  • evaluateJavascript — uses iframe.contentWindow.eval() internally, which is blocked by the browser due to cross-origin restrictions. The error is silently caught, and null is returned.
  • onConsoleMessage — web_support.js tries to override iframe.contentWindow.console.log to intercept messages, which also fails due to cross-origin restrictions.
  • goBack / goForward — use iframe.contentWindow.history, also blocked.

Essentially, InAppWebView with initialData on web becomes a write-only iframe — content loads and renders, but no two-way communication between Dart and JavaScript is possible.

Fix

In flutter_inappwebview_web/lib/web/in_app_web_view_web_element.dart, method loadData:

// Before:> iframe.src = 'data:$mimeType,' + Uri.encodeComponent(data);> > // After:> iframe.srcdoc = data.toJS;>

srcdoc iframes inherit the parent page's origin, making contentWindow fully accessible. This fixes evaluateJavascript, onConsoleMessage, history navigation, and all other contentWindow-dependent features.

Notes

  • srcdoc only supports text/html content. The mimeType parameter is effectively ignored. In practice, initialData / loadData is almost exclusively used with HTML content.
  • srcdoc is supported in all modern browsers: https://caniuse.com/iframe-srcdoc
  • This change does not affect loadUrl or loadFile.

Test plan

  • Load InAppWebView with initialData containing HTML + JavaScript on web
  • Verify evaluateJavascript executes JS code and returns results
  • Verify onConsoleMessage receives console.log messages from the iframe
  • Verify goBack / goForward work within the iframe

… same-origin и позволяет работать evaluateJavascript и перехвату console.log на вебе
@probot-autolabeler probot-autolabeler Bot added android iOS linux Linux platform macOS macOS platform platform_interface Platform Interface plugin flutter_inappwebview plugin web windows Windows platform labels Mar 4, 2026
@zenalex

zenalex commented Apr 19, 2026

Copy link
Copy Markdown
Author

When a parent widget (e.g. a PageView page) disposes the
CustomPlatformView while async work is still in flight, the State is
already unmounted and the RenderBox detached. The existing code then:

  • calls setState() after dispose
    • onPlatformViewCreated callback (initialize completes late)
    • cursor stream listener
  • calls RenderBox.localToGlobal() on a detached render object from
    _reportWidgetPosition after awaiting _controller.ready, tripping
    the "RenderBox was not laid out / not attached" assertion and
    crashing the app on Windows.

Reproduction: place an InAppWebView inside a vertically-scrolled
PageView.builder (TikTok-style feed) and swipe between pages — the
pages going off-screen get disposed while their webview is still
finishing initialization, and the assertion fires.

Fix: add mounted / RenderBox.attached guards before every post-await
side effect in _CustomPlatformViewState:

  • onPlatformViewCreated setState()
  • post-frame callback
  • cursor subscription setState()
  • _reportSurfaceSize after await _controller.ready
  • _reportWidgetPosition after await _controller.ready

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

android documentation iOS legal linux Linux platform macOS macOS platform platform_interface Platform Interface plugin flutter_inappwebview plugin web windows Windows platform

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant